1*0fca8acaSbluhm /*	$OpenBSD: open_memstreamtest.c,v 1.6 2019/05/13 02:54:54 bluhm Exp $ */
2ee8af14aSmpi 
323468c0eSmpi /*
423468c0eSmpi  * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
523468c0eSmpi  *
623468c0eSmpi  * Permission to use, copy, modify, and distribute this software for any
723468c0eSmpi  * purpose with or without fee is hereby granted, provided that the above
823468c0eSmpi  * copyright notice and this permission notice appear in all copies.
923468c0eSmpi  *
1023468c0eSmpi  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1123468c0eSmpi  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1223468c0eSmpi  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1323468c0eSmpi  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1423468c0eSmpi  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1523468c0eSmpi  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1623468c0eSmpi  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1723468c0eSmpi  */
1823468c0eSmpi 
1923468c0eSmpi #include <err.h>
2023468c0eSmpi #include <stdio.h>
2123468c0eSmpi #include <stdlib.h>
2223468c0eSmpi #include <string.h>
2323468c0eSmpi #include <unistd.h>
2423468c0eSmpi 
2523468c0eSmpi #define OFFSET 16384
2623468c0eSmpi 
27840b6301Sguenther const char start[] = "start";
28840b6301Sguenther const char hello[] = "hello";
29840b6301Sguenther 
3023468c0eSmpi int
main(void)3123468c0eSmpi main(void)
3223468c0eSmpi {
3323468c0eSmpi 	FILE	*fp;
3423468c0eSmpi 	char	*buf = (char *)0xff;
3523468c0eSmpi 	size_t	 size = 0;
3623468c0eSmpi 	off_t	 off;
37840b6301Sguenther 	int	 i, failures = 0;
3823468c0eSmpi 
3923468c0eSmpi 	if ((fp = open_memstream(&buf, &size)) == NULL) {
4023468c0eSmpi 		warn("open_memstream failed");
4123468c0eSmpi 		return (1);
4223468c0eSmpi 	}
4323468c0eSmpi 
4423468c0eSmpi 	off = ftello(fp);
4523468c0eSmpi 	if (off != 0) {
4623468c0eSmpi 		warnx("ftello failed. (1)");
4723468c0eSmpi 		failures++;
4823468c0eSmpi 	}
4923468c0eSmpi 
5023468c0eSmpi 	if (fflush(fp) != 0) {
5123468c0eSmpi 		warnx("fflush failed. (2)");
5223468c0eSmpi 		failures++;
5323468c0eSmpi 	}
5423468c0eSmpi 
5523468c0eSmpi 	if (size != 0) {
5623468c0eSmpi 		warnx("string should be empty. (3)");
5723468c0eSmpi 		failures++;
5823468c0eSmpi 	}
5923468c0eSmpi 
6023468c0eSmpi 	if (buf == (char *)0xff) {
6123468c0eSmpi 		warnx("buf not updated. (4)");
6223468c0eSmpi 		failures++;
6323468c0eSmpi 	}
6423468c0eSmpi 
6523468c0eSmpi 	if (fseek(fp, OFFSET, SEEK_SET) != 0) {
6623468c0eSmpi 		warnx("failed to fseek. (5)");
6723468c0eSmpi 		failures++;
6823468c0eSmpi 	}
6923468c0eSmpi 
70840b6301Sguenther 	if (fprintf(fp, hello) == EOF) {
7123468c0eSmpi 		warnx("fprintf failed. (6)");
7223468c0eSmpi 		failures++;
7323468c0eSmpi 	}
7423468c0eSmpi 
75840b6301Sguenther 	if (fflush(fp) == EOF) {
76840b6301Sguenther 		warnx("fflush failed. (7)");
7723468c0eSmpi 		failures++;
7823468c0eSmpi 	}
7923468c0eSmpi 
80840b6301Sguenther 	if (size != OFFSET + sizeof(hello)-1) {
812b1dab59Sguenther 		warnx("failed, size %zu should be %zu. (8)",
82840b6301Sguenther 		    size, OFFSET + sizeof(hello)-1);
83840b6301Sguenther 		failures++;
84840b6301Sguenther 	}
85840b6301Sguenther 
86840b6301Sguenther 	if (fseek(fp, 0, SEEK_SET) != 0) {
87840b6301Sguenther 		warnx("failed to fseek. (9)");
88840b6301Sguenther 		failures++;
89840b6301Sguenther 	}
90840b6301Sguenther 
91840b6301Sguenther 	if (fprintf(fp, start) == EOF) {
92840b6301Sguenther 		warnx("fprintf failed. (10)");
93840b6301Sguenther 		failures++;
94840b6301Sguenther 	}
95840b6301Sguenther 
96840b6301Sguenther 	if (fflush(fp) == EOF) {
97840b6301Sguenther 		warnx("fflush failed. (11)");
98840b6301Sguenther 		failures++;
99840b6301Sguenther 	}
100840b6301Sguenther 
101840b6301Sguenther 	if (size != sizeof(start)-1) {
1022b1dab59Sguenther 		warnx("failed, size %zu should be %zu. (12)",
103840b6301Sguenther 		    size, sizeof(start)-1);
10423468c0eSmpi 		failures++;
10523468c0eSmpi 	}
10623468c0eSmpi 
10723468c0eSmpi 	/* Needed for sparse files */
108840b6301Sguenther 	if (strncmp(buf, start, sizeof(start)-1) != 0) {
109840b6301Sguenther 		warnx("failed, buffer didn't start with '%s'. (13)", start);
110840b6301Sguenther 		failures++;
111840b6301Sguenther 	}
112840b6301Sguenther 	for (i = sizeof(start)-1; i < OFFSET; i++)
113840b6301Sguenther 		if (buf[i] != '\0') {
114840b6301Sguenther 			warnx("failed, buffer non zero (offset %d). (14)", i);
11523468c0eSmpi 			failures++;
11623468c0eSmpi 			break;
11723468c0eSmpi 		}
11823468c0eSmpi 
119840b6301Sguenther 	if (memcmp(buf + OFFSET, hello, sizeof(hello)-1) != 0) {
120840b6301Sguenther 		warnx("written string incorrect. (15)");
121840b6301Sguenther 		failures++;
122840b6301Sguenther 	}
123840b6301Sguenther 
124840b6301Sguenther 	/* verify that simply seeking past the end doesn't increase the size */
125840b6301Sguenther 	if (fseek(fp, 100, SEEK_END) != 0) {
126840b6301Sguenther 		warnx("failed to fseek. (16)");
127840b6301Sguenther 		failures++;
128840b6301Sguenther 	}
129840b6301Sguenther 
1302b1dab59Sguenther 	if (fflush(fp) == EOF) {
1312b1dab59Sguenther 		warnx("fflush failed. (17)");
132840b6301Sguenther 		failures++;
133840b6301Sguenther 	}
134840b6301Sguenther 
135840b6301Sguenther 	if (size != OFFSET + sizeof(hello)-1) {
1362b1dab59Sguenther 		warnx("failed, size %zu should be %zu. (18)",
137840b6301Sguenther 		    size, OFFSET + sizeof(hello)-1);
13823468c0eSmpi 		failures++;
13923468c0eSmpi 	}
14023468c0eSmpi 
141*0fca8acaSbluhm 	if (fseek(fp, -1, SEEK_END) != 0) {
142ee8af14aSmpi 		warnx("failed to fseek. (19)");
143ee8af14aSmpi 		failures++;
144ee8af14aSmpi 	}
145ee8af14aSmpi 
146*0fca8acaSbluhm 	if (fseek(fp, 8, SEEK_SET) != 0) {
147*0fca8acaSbluhm 		warnx("failed to fseek. (20)");
148*0fca8acaSbluhm 		failures++;
149*0fca8acaSbluhm 	}
150*0fca8acaSbluhm 
151ee8af14aSmpi 	if (ftell(fp) != 8) {
152*0fca8acaSbluhm 		warnx("failed seek test. (21)");
153ee8af14aSmpi 		failures++;
154ee8af14aSmpi 	}
155ee8af14aSmpi 
156ee8af14aSmpi 	/* Try to seek backward */
157ee8af14aSmpi 	if (fseek(fp, -1, SEEK_CUR) != 0) {
158*0fca8acaSbluhm 		warnx("failed to fseek. (22)");
159ee8af14aSmpi 		failures++;
160ee8af14aSmpi 	}
161ee8af14aSmpi 
162ee8af14aSmpi 	if (ftell(fp) != 7) {
163*0fca8acaSbluhm 		warnx("failed seeking backward. (23)");
164ee8af14aSmpi 		failures++;
165ee8af14aSmpi 	}
166ee8af14aSmpi 
1672b1dab59Sguenther 	if (fseek(fp, 5, SEEK_CUR) != 0) {
168384a789dSyasuoka 		warnx("failed to fseek. (24)");
169384a789dSyasuoka 		failures++;
170384a789dSyasuoka 	}
171384a789dSyasuoka 
1722b1dab59Sguenther 	if (fclose(fp) == EOF) {
173384a789dSyasuoka 		warnx("fclose failed. (25)");
1742b1dab59Sguenther 		failures++;
1752b1dab59Sguenther 	}
1762b1dab59Sguenther 
1772b1dab59Sguenther 	if (size != 12) {
178384a789dSyasuoka 		warnx("failed, size %zu should be %u.  (26)",
1792b1dab59Sguenther 		    size, 12);
1802b1dab59Sguenther 		failures++;
1812b1dab59Sguenther 	}
1822b1dab59Sguenther 
18323468c0eSmpi 	free(buf);
18423468c0eSmpi 
18523468c0eSmpi 	return (failures);
18623468c0eSmpi }
187