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