1 /*	$OpenBSD: open_memstreamtest.c,v 1.6 2019/05/13 02:54:54 bluhm Exp $ */
2 
3 /*
4  * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <err.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 
25 #define OFFSET 16384
26 
27 const char start[] = "start";
28 const char hello[] = "hello";
29 
30 int
main(void)31 main(void)
32 {
33 	FILE	*fp;
34 	char	*buf = (char *)0xff;
35 	size_t	 size = 0;
36 	off_t	 off;
37 	int	 i, failures = 0;
38 
39 	if ((fp = open_memstream(&buf, &size)) == NULL) {
40 		warn("open_memstream failed");
41 		return (1);
42 	}
43 
44 	off = ftello(fp);
45 	if (off != 0) {
46 		warnx("ftello failed. (1)");
47 		failures++;
48 	}
49 
50 	if (fflush(fp) != 0) {
51 		warnx("fflush failed. (2)");
52 		failures++;
53 	}
54 
55 	if (size != 0) {
56 		warnx("string should be empty. (3)");
57 		failures++;
58 	}
59 
60 	if (buf == (char *)0xff) {
61 		warnx("buf not updated. (4)");
62 		failures++;
63 	}
64 
65 	if (fseek(fp, OFFSET, SEEK_SET) != 0) {
66 		warnx("failed to fseek. (5)");
67 		failures++;
68 	}
69 
70 	if (fprintf(fp, hello) == EOF) {
71 		warnx("fprintf failed. (6)");
72 		failures++;
73 	}
74 
75 	if (fflush(fp) == EOF) {
76 		warnx("fflush failed. (7)");
77 		failures++;
78 	}
79 
80 	if (size != OFFSET + sizeof(hello)-1) {
81 		warnx("failed, size %zu should be %zu. (8)",
82 		    size, OFFSET + sizeof(hello)-1);
83 		failures++;
84 	}
85 
86 	if (fseek(fp, 0, SEEK_SET) != 0) {
87 		warnx("failed to fseek. (9)");
88 		failures++;
89 	}
90 
91 	if (fprintf(fp, start) == EOF) {
92 		warnx("fprintf failed. (10)");
93 		failures++;
94 	}
95 
96 	if (fflush(fp) == EOF) {
97 		warnx("fflush failed. (11)");
98 		failures++;
99 	}
100 
101 	if (size != sizeof(start)-1) {
102 		warnx("failed, size %zu should be %zu. (12)",
103 		    size, sizeof(start)-1);
104 		failures++;
105 	}
106 
107 	/* Needed for sparse files */
108 	if (strncmp(buf, start, sizeof(start)-1) != 0) {
109 		warnx("failed, buffer didn't start with '%s'. (13)", start);
110 		failures++;
111 	}
112 	for (i = sizeof(start)-1; i < OFFSET; i++)
113 		if (buf[i] != '\0') {
114 			warnx("failed, buffer non zero (offset %d). (14)", i);
115 			failures++;
116 			break;
117 		}
118 
119 	if (memcmp(buf + OFFSET, hello, sizeof(hello)-1) != 0) {
120 		warnx("written string incorrect. (15)");
121 		failures++;
122 	}
123 
124 	/* verify that simply seeking past the end doesn't increase the size */
125 	if (fseek(fp, 100, SEEK_END) != 0) {
126 		warnx("failed to fseek. (16)");
127 		failures++;
128 	}
129 
130 	if (fflush(fp) == EOF) {
131 		warnx("fflush failed. (17)");
132 		failures++;
133 	}
134 
135 	if (size != OFFSET + sizeof(hello)-1) {
136 		warnx("failed, size %zu should be %zu. (18)",
137 		    size, OFFSET + sizeof(hello)-1);
138 		failures++;
139 	}
140 
141 	if (fseek(fp, -1, SEEK_END) != 0) {
142 		warnx("failed to fseek. (19)");
143 		failures++;
144 	}
145 
146 	if (fseek(fp, 8, SEEK_SET) != 0) {
147 		warnx("failed to fseek. (20)");
148 		failures++;
149 	}
150 
151 	if (ftell(fp) != 8) {
152 		warnx("failed seek test. (21)");
153 		failures++;
154 	}
155 
156 	/* Try to seek backward */
157 	if (fseek(fp, -1, SEEK_CUR) != 0) {
158 		warnx("failed to fseek. (22)");
159 		failures++;
160 	}
161 
162 	if (ftell(fp) != 7) {
163 		warnx("failed seeking backward. (23)");
164 		failures++;
165 	}
166 
167 	if (fseek(fp, 5, SEEK_CUR) != 0) {
168 		warnx("failed to fseek. (24)");
169 		failures++;
170 	}
171 
172 	if (fclose(fp) == EOF) {
173 		warnx("fclose failed. (25)");
174 		failures++;
175 	}
176 
177 	if (size != 12) {
178 		warnx("failed, size %zu should be %u.  (26)",
179 		    size, 12);
180 		failures++;
181 	}
182 
183 	free(buf);
184 
185 	return (failures);
186 }
187