1 /* $OpenBSD: fmemopentest.c,v 1.4 2020/08/17 16:17:39 millert 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 int
simpletest(void)26 simpletest(void)
27 {
28 FILE *s1, *s2;
29 char string[] = "fmemopen test string!";
30 char buffer[1024], *buf = NULL;
31 size_t len;
32 int c, failures = 0;
33
34 s1 = fmemopen(string, strlen(string) + 1, "r");
35 if (s1 == NULL) {
36 warn("unable to open a stream s1");
37 return (1);
38 }
39
40 s2 = fmemopen(buf, 22, "w+");
41 if (s2 == NULL) {
42 warn("unable to create a stream s2");
43 fclose(s1);
44 return (1);
45 }
46
47 while ((c = fgetc(s1)) != EOF)
48 fputc(c, s2);
49
50 if (ftell(s2) != strlen(string) + 1) {
51 warnx("failed copy test (1)");
52 failures++;
53 }
54 fclose(s1);
55
56 fseek(s2, 0, SEEK_SET);
57 if (ftell(s2) != 0) {
58 warnx("failed seek test (2)");
59 failures++;
60 }
61
62 len = fread(buffer, 1, sizeof(buffer) - 1, s2);
63 if (len != strlen(string) + 1) {
64 warnx("failed read test (3) %zu != %zu",
65 len, strlen(string) + 1);
66 failures++;
67 }
68
69 return (failures);
70 }
71
72 int
appendtest(const char * mode)73 appendtest(const char *mode)
74 {
75 FILE *s1;
76 char string[] = "hello\0 test number 2";
77 char buffer[256];
78 size_t len;
79 int failures = 0;
80
81 s1 = fmemopen(string, 19, mode);
82 if (s1 == NULL)
83 return (1);
84
85 fseek(s1, 0, SEEK_SET);
86 if (ftell(s1) != 0) {
87 warnx("failed seek test [%s] (4)", mode);
88 failures++;
89 }
90
91 /* write should append even though seek position is 0 */
92 len = fwrite(" world", 1, 6, s1);
93 if (len != 6) {
94 warnx("failed write test [%s] (5)", mode);
95 failures++;
96 }
97
98 if (ftell(s1) != strlen("hello world")) {
99 warnx("failed seek test [%s] (6)", mode);
100 failures++;
101 }
102
103 if (mode[1] == '+') {
104 fseek(s1, 0, SEEK_SET);
105 len = fread(buffer, 1, sizeof(buffer) - 1, s1);
106 if (len == 0 || strncmp(string, buffer, len)) {
107 warnx("failed compare test [%s] (7)", mode);
108 failures++;
109 }
110 }
111
112 if (strcmp(string, "hello world")) {
113 warnx("failed compare test [%s] (8)", mode);
114 failures++;
115 }
116
117 if (strcmp(string + strlen(string) + 1, "number 2")) {
118 warnx("failed compare test [%s] (9)", mode);
119 failures++;
120 }
121
122 return (failures);
123 }
124
125 int
updatetest(void)126 updatetest(void)
127 {
128 FILE *s1;
129 char string[] = "bah, what a day";
130 char buffer[256];
131 size_t len;
132 int failures = 0;
133
134 s1 = fmemopen(string, 19, "r+");
135 if (s1 == NULL)
136 return (1);
137
138 if (ftell(s1) != 0) {
139 warnx("failed seek test (10)");
140 failures++;
141 }
142
143 len = fwrite("oh frabjous", 1, 11, s1);
144 if (len != 11) {
145 warnx("failed write test (11)");
146 failures++;
147 }
148
149 fseek(s1, 0, SEEK_SET);
150 len = fread(buffer, 1, sizeof(buffer) - 1, s1);
151 if (len == 0 || strncmp(string, buffer, len)) {
152 warnx("failed compare test (12)");
153 failures++;
154 }
155
156 if (strcmp(string, "oh frabjous day")) {
157 warnx("failed compare test (13)");
158 failures++;
159 }
160
161 return (failures);
162 }
163
164 int
writetest(const char * mode)165 writetest(const char *mode)
166 {
167 FILE *s1;
168 char string[] = "super test number 3";
169 char buffer[256];
170 size_t len, slen;
171 int failures = 0;
172
173 slen = strlen(string) + 1;
174
175 s1 = fmemopen(string, slen, mode);
176 if (s1 == NULL)
177 return (1);
178
179 len = fwrite("short", 1, 5, s1);
180 if (len != strlen("short")) {
181 warnx("failed write test [%s] (14)", mode);
182 failures++;
183 }
184 fclose(s1);
185
186 s1 = fmemopen(string, slen, "r");
187 if (s1 == NULL) {
188 warnx("failed open test [%s] (15)", mode);
189 failures++;
190 }
191
192 len = fread(buffer, 1, sizeof(buffer) - 1, s1);
193 if (len == 0 || strncmp(string, buffer, len)) {
194 warnx("failed compare test [%s] (16)", mode);
195 failures++;
196 }
197
198 if (strcmp(string, "short")) {
199 warnx("failed compare test [%s] (17)", mode);
200 failures++;
201 }
202
203 if (strcmp(string + strlen(string) + 1, "test number 3")) {
204 warnx("failed compare test [%s] (18)", mode);
205 failures++;
206 }
207
208 return (failures);
209 }
210
211 int
seektest(void)212 seektest(void)
213 {
214 FILE *s1;
215 char string[] = "long string for testing seek";
216 size_t len, slen;
217 int failures = 0;
218
219 slen = strlen(string) + 1;
220
221 s1 = fmemopen(string, slen, "r");
222 if (s1 == NULL)
223 return (1);
224
225 if (fseek(s1, 8, SEEK_SET) != 0) {
226 warnx("failed to fseek. (19)");
227 failures++;
228 }
229
230 if (ftell(s1) != 8) {
231 warnx("failed seek test. (20)");
232 failures++;
233 }
234
235 /* Try to seek backward */
236 if (fseek(s1, -1, SEEK_CUR) != 0) {
237 warnx("failed to fseek. (21)");
238 failures++;
239 }
240
241 if (ftell(s1) != 7) {
242 warnx("failed seeking backward. (22)");
243 failures++;
244 }
245
246 return (failures);
247 }
248
249 int
main(void)250 main(void)
251 {
252 int failures = 0;
253
254 failures += simpletest();
255 failures += appendtest("a");
256 failures += appendtest("a+");
257 failures += updatetest();
258 failures += writetest("w");
259 failures += writetest("w+");
260 failures += seektest();
261
262 return (failures);
263 }
264