]> git.saurik.com Git - apple/libc.git/blob - tests/netbsd_fmemopen.c
Libc-1439.100.3.tar.gz
[apple/libc.git] / tests / netbsd_fmemopen.c
1 /* $NetBSD: t_fmemopen.c,v 1.4 2013/10/19 17:45:00 christos Exp $ */
2
3 /*-
4 * Copyright (c)2010 Takehiko NOZAKI,
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
29
30 #include <errno.h>
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <limits.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include <darwintest.h>
38
39 static const char *mode_rwa[] = {
40 "r", "rb", "r+", "rb+", "r+b",
41 "w", "wb", "w+", "wb+", "w+b",
42 "a", "ab", "a+", "ab+", "a+b",
43 NULL
44 };
45
46 static const char *mode_r[] = { "r", "rb", "r+", "rb+", "r+b", NULL };
47 static const char *mode_w[] = { "w", "wb", "w+", "wb+", "w+b", NULL };
48 static const char *mode_a[] = { "a", "ab", "a+", "ab+", "a+b", NULL };
49
50 static struct testcase {
51 const char *s;
52 off_t n;
53 } testcases[] = {
54 #define TESTSTR(s) { s, sizeof(s)-1 }
55 TESTSTR("\0he quick brown fox jumps over the lazy dog"),
56 TESTSTR("T\0e quick brown fox jumps over the lazy dog"),
57 TESTSTR("Th\0 quick brown fox jumps over the lazy dog"),
58 TESTSTR("The\0quick brown fox jumps over the lazy dog"),
59 TESTSTR("The \0uick brown fox jumps over the lazy dog"),
60 TESTSTR("The q\0ick brown fox jumps over the lazy dog"),
61 TESTSTR("The qu\0ck brown fox jumps over the lazy dog"),
62 TESTSTR("The qui\0k brown fox jumps over the lazy dog"),
63 TESTSTR("The quic\0 brown fox jumps over the lazy dog"),
64 TESTSTR("The quick\0brown fox jumps over the lazy dog"),
65 TESTSTR("The quick \0rown fox jumps over the lazy dog"),
66 TESTSTR("The quick b\0own fox jumps over the lazy dog"),
67 TESTSTR("The quick br\0wn fox jumps over the lazy dog"),
68 TESTSTR("The quick bro\0n fox jumps over the lazy dog"),
69 TESTSTR("The quick brow\0 fox jumps over the lazy dog"),
70 TESTSTR("The quick brown\0fox jumps over the lazy dog"),
71 TESTSTR("The quick brown \0ox jumps over the lazy dog"),
72 TESTSTR("The quick brown f\0x jumps over the lazy dog"),
73 TESTSTR("The quick brown fo\0 jumps over the lazy dog"),
74 TESTSTR("The quick brown fox\0jumps over the lazy dog"),
75 TESTSTR("The quick brown fox \0umps over the lazy dog"),
76 TESTSTR("The quick brown fox j\0mps over the lazy dog"),
77 TESTSTR("The quick brown fox ju\0ps over the lazy dog"),
78 TESTSTR("The quick brown fox jum\0s over the lazy dog"),
79 TESTSTR("The quick brown fox jump\0 over the lazy dog"),
80 TESTSTR("The quick brown fox jumps\0over the lazy dog"),
81 TESTSTR("The quick brown fox jumps \0ver the lazy dog"),
82 TESTSTR("The quick brown fox jumps o\0er the lazy dog"),
83 TESTSTR("The quick brown fox jumps ov\0r the lazy dog"),
84 TESTSTR("The quick brown fox jumps ove\0 the lazy dog"),
85 TESTSTR("The quick brown fox jumps over\0the lazy dog"),
86 TESTSTR("The quick brown fox jumps over \0he lazy dog"),
87 TESTSTR("The quick brown fox jumps over t\0e lazy dog"),
88 TESTSTR("The quick brown fox jumps over th\0 lazy dog"),
89 TESTSTR("The quick brown fox jumps over the\0lazy dog"),
90 TESTSTR("The quick brown fox jumps over the \0azy dog"),
91 TESTSTR("The quick brown fox jumps over the l\0zy dog"),
92 TESTSTR("The quick brown fox jumps over the la\0y dog"),
93 TESTSTR("The quick brown fox jumps over the laz\0 dog"),
94 TESTSTR("The quick brown fox jumps over the lazy\0dog"),
95 TESTSTR("The quick brown fox jumps over the lazy \0og"),
96 TESTSTR("The quick brown fox jumps over the lazy d\0g"),
97 TESTSTR("The quick brown fox jumps over the lazy do\0"),
98 TESTSTR("The quick brown fox jumps over the lazy dog"),
99 { NULL, 0 },
100 };
101
102 T_DECL(netbsd_fmemopen_test00, "")
103 {
104 const char **p;
105 char buf[BUFSIZ];
106 FILE *fp;
107
108 for (p = &mode_rwa[0]; *p != NULL; ++p) {
109 fp = fmemopen(&buf[0], sizeof(buf), *p);
110 /*
111 * Upon successful completion, fmemopen() shall return a pointer to the
112 * object controlling the stream.
113 */
114 T_EXPECT_NOTNULL(fp, NULL);
115
116 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
117 }
118 }
119
120 T_DECL(netbsd_fmemopen_test01, "")
121 {
122 const char **p;
123 const char *mode[] = {
124 "r+", "rb+", "r+b",
125 "w+", "wb+", "w+b",
126 "a+", "ab+", "a+b",
127 NULL
128 };
129 FILE *fp;
130
131 for (p = &mode[0]; *p != NULL; ++p) {
132 /*
133 * If a null pointer is specified as the buf argument, fmemopen() shall
134 * allocate size bytes of memory as if by a call to malloc().
135 */
136 fp = fmemopen(NULL, BUFSIZ, *p);
137 T_EXPECT_NOTNULL(fp, NULL);
138
139 /*
140 * If buf is a null pointer, the initial position shall always be set
141 * to the beginning of the buffer.
142 */
143 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
144
145 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
146 }
147 }
148
149 T_DECL(netbsd_fmemopen_test02, "")
150 {
151 const char **p;
152 char buf[BUFSIZ];
153 FILE *fp;
154
155 for (p = &mode_r[0]; *p != NULL; ++p) {
156
157 memset(&buf[0], 0x1, sizeof(buf));
158 fp = fmemopen(&buf[0], sizeof(buf), *p);
159 T_EXPECT_NOTNULL(fp, NULL);
160
161 /*
162 * This position is initially set to either the beginning of the buffer
163 * (for r and w modes)
164 */
165 T_EXPECT_EQ((unsigned char)buf[0], 0x1, NULL);
166 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
167
168 /*
169 * The stream also maintains the size of the current buffer contents.
170 * For modes r and r+ the size is set to the value given by the size argument.
171 */
172 #if !defined(__GLIBC__)
173 T_EXPECT_POSIX_ZERO(fseeko(fp, (off_t)0, SEEK_END), NULL);
174 T_EXPECT_EQ(ftello(fp), (off_t)sizeof(buf), NULL);
175 #endif
176 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
177 }
178 }
179
180 T_DECL(netbsd_fmemopen_test03, "")
181 {
182 const char **p;
183 char buf[BUFSIZ];
184 FILE *fp;
185
186 for (p = &mode_w[0]; *p != NULL; ++p) {
187
188 memset(&buf[0], 0x1, sizeof(buf));
189 fp = fmemopen(&buf[0], sizeof(buf), *p);
190 T_EXPECT_NOTNULL(fp, NULL);
191
192 /*
193 * This position is initially set to either the beginning of the buffer
194 * (for r and w modes)
195 */
196 T_EXPECT_EQ(buf[0], '\0', NULL);
197 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
198
199 /*
200 * For modes w and w+ the initial size is zero
201 */
202 T_EXPECT_POSIX_ZERO(fseeko(fp, (off_t)0, SEEK_END), NULL);
203 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
204
205 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
206 }
207 }
208
209 T_DECL(netbsd_fmemopen_test04, "")
210 {
211 const char **p;
212 char buf[BUFSIZ];
213 FILE *fp;
214
215 /*
216 * or to the first null byte in the buffer (for a modes)
217 */
218 for (p = &mode_a[0]; *p != NULL; ++p) {
219
220 memset(&buf[0], 0x1, sizeof(buf));
221 fp = fmemopen(&buf[0], sizeof(buf), *p);
222 T_EXPECT_NOTNULL(fp, NULL);
223
224 T_EXPECT_EQ((unsigned char)buf[0], 0x1, NULL);
225
226 /* If no null byte is found in append mode,
227 * the initial position is set to one byte after the end of the buffer.
228 */
229 #if !defined(__GLIBC__)
230 T_EXPECT_EQ(ftello(fp), (off_t)sizeof(buf), NULL);
231 #endif
232
233 /*
234 * and for modes a and a+ the initial size is either the position of the
235 * first null byte in the buffer or the value of the size argument
236 * if no null byte is found.
237 */
238 #if !defined(__GLIBC__)
239 T_EXPECT_POSIX_ZERO(fseeko(fp, (off_t)0, SEEK_END), NULL);
240 T_EXPECT_EQ(ftello(fp), (off_t)sizeof(buf), NULL);
241 #endif
242
243 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
244 }
245 }
246
247 T_DECL(netbsd_fmemopen_test05, "")
248 {
249 const char **p;
250 FILE *fp;
251 char buf[BUFSIZ];
252
253 for (p = &mode_rwa[0]; *p != NULL; ++p) {
254 /*
255 * Otherwise, a null pointer shall be returned, and errno shall be set
256 * to indicate the error.
257 */
258 errno = 0;
259 fp = fmemopen(NULL, (size_t)0, *p);
260 T_EXPECT_NULL(fp, NULL);
261 T_EXPECT_EQ(errno, EINVAL, NULL);
262
263 errno = 0;
264 fp = fmemopen((void *)&buf[0], 0, *p);
265 T_EXPECT_NULL(fp, NULL);
266 T_EXPECT_EQ(errno, EINVAL, NULL);
267 }
268 }
269
270 T_DECL(netbsd_fmemopen_test06, "")
271 {
272 const char **p;
273 const char *mode[] = { "", " ", "???", NULL };
274 FILE *fp;
275
276 for (p = &mode[0]; *p != NULL; ++p) {
277 /*
278 * The value of the mode argument is not valid.
279 */
280 fp = fmemopen(NULL, 1, *p);
281 T_EXPECT_NULL(fp, NULL);
282 T_EXPECT_EQ(errno, EINVAL, NULL);
283 }
284 }
285
286 T_DECL(netbsd_fmemopen_test07, "")
287 {
288 #if !defined(__GLIBC__)
289 const char **p;
290 const char *mode[] = {
291 "r", "rb",
292 "w", "wb",
293 "a", "ab",
294 NULL
295 };
296 FILE *fp;
297
298 for (p = &mode[0]; *p != NULL; ++p) {
299 /*
300 * Because this feature is only useful when the stream is opened for updating
301 * (because there is no way to get a pointer to the buffer) the fmemopen()
302 * call may fail if the mode argument does not include a '+' .
303 */
304 errno = 0;
305 fp = fmemopen(NULL, 1, *p);
306 T_EXPECT_NULL(fp, NULL);
307 T_EXPECT_EQ(errno, EINVAL, NULL);
308 }
309 #endif
310 }
311
312 T_DECL(netbsd_fmemopen_test08, "")
313 {
314 #if !defined(__GLIBC__)
315 const char **p;
316 const char *mode[] = {
317 "r+", "rb+", "r+b",
318 "w+", "wb+", "w+b",
319 "a+", "ab+", "a+b",
320 NULL
321 };
322 FILE *fp;
323
324 for (p = &mode[0]; *p != NULL; ++p) {
325 /*
326 * The buf argument is a null pointer and the allocation of a buffer of
327 * length size has failed.
328 */
329 fp = fmemopen(NULL, SIZE_MAX, *p);
330 T_EXPECT_NULL(fp, NULL);
331 T_EXPECT_EQ(errno, ENOMEM, NULL);
332 }
333 #endif
334 }
335
336 /*
337 * test09 - test14:
338 * An attempt to seek a memory buffer stream to a negative position or to a
339 * position larger than the buffer size given in the size argument shall fail.
340 */
341
342 T_DECL(netbsd_fmemopen_test09, "")
343 {
344 struct testcase *t;
345 const char **p;
346 char buf[BUFSIZ];
347 FILE *fp;
348 off_t i;
349
350 for (t = &testcases[0]; t->s != NULL; ++t) {
351 for (p = &mode_rwa[0]; *p != NULL; ++p) {
352
353 memcpy(&buf[0], t->s, t->n);
354 fp = fmemopen(&buf[0], (size_t)t->n, *p);
355 T_EXPECT_NOTNULL(fp, NULL);
356
357 /*
358 * test fmemopen_seek(SEEK_SET)
359 */
360 /* zero */
361 T_EXPECT_POSIX_ZERO(fseeko(fp, (off_t)0, SEEK_SET), NULL);
362 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
363
364 /* positive */
365 for (i = (off_t)1; i <= (off_t)t->n; ++i) {
366 T_EXPECT_POSIX_ZERO(fseeko(fp, i, SEEK_SET), NULL);
367 T_EXPECT_EQ(ftello(fp), i, NULL);
368 }
369 /* positive + OOB */
370 T_EXPECT_EQ(fseeko(fp, t->n + 1, SEEK_SET), -1, NULL);
371 T_EXPECT_EQ(ftello(fp), t->n, NULL);
372
373 /* negative + OOB */
374 T_EXPECT_EQ(fseeko(fp, (off_t)-1, SEEK_SET), -1, NULL);
375 T_EXPECT_EQ(ftello(fp), t->n, NULL);
376
377 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
378 }
379 }
380 }
381
382 static const char *mode_rw[] = {
383 "r", "rb", "r+", "rb+", "r+b",
384 "w", "wb", "w+", "wb+", "w+b",
385 NULL
386 };
387
388 T_DECL(netbsd_fmemopen_test10, "")
389 {
390 struct testcase *t;
391 off_t i;
392 const char **p;
393 char buf[BUFSIZ];
394 FILE *fp;
395
396 for (t = &testcases[0]; t->s != NULL; ++t) {
397 for (p = &mode_rw[0]; *p != NULL; ++p) {
398
399 memcpy(&buf[0], t->s, t->n);
400 fp = fmemopen(&buf[0], (size_t)t->n, *p);
401 T_EXPECT_NOTNULL(fp, NULL);
402
403 /*
404 * test fmemopen_seek(SEEK_CUR)
405 */
406 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
407
408 /* zero */
409 T_EXPECT_POSIX_ZERO(fseeko(fp, (off_t)0, SEEK_CUR), NULL);
410 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
411
412 /* negative & OOB */
413 T_EXPECT_EQ(fseeko(fp, (off_t)-1, SEEK_CUR), -1, NULL);
414 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
415
416 /* positive */
417 for (i = 0; i < (off_t)t->n; ++i) {
418 T_EXPECT_POSIX_ZERO(fseeko(fp, (off_t)1, SEEK_CUR), NULL);
419 T_EXPECT_EQ(ftello(fp), i + 1, NULL);
420 }
421
422 /* positive & OOB */
423 T_EXPECT_EQ(fseeko(fp, (off_t)1, SEEK_CUR), -1, NULL);
424 T_EXPECT_EQ(ftello(fp), (off_t)t->n, NULL);
425
426 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
427 }
428 }
429 }
430
431 T_DECL(netbsd_fmemopen_test11, "")
432 {
433 struct testcase *t;
434 off_t len, rest, i;
435 const char **p;
436 char buf[BUFSIZ];
437 FILE *fp;
438
439 /* test fmemopen_seek(SEEK_CUR) */
440 for (t = &testcases[0]; t->s != NULL; ++t) {
441 len = (off_t)strnlen(t->s, (size_t)t->n);
442 rest = (off_t)t->n - len;
443 for (p = &mode_a[0]; *p != NULL; ++p) {
444
445 memcpy(&buf[0], t->s, t->n);
446 fp = fmemopen(&buf[0], (size_t)t->n, *p);
447 T_EXPECT_NOTNULL(fp, NULL);
448 /*
449 * test fmemopen_seek(SEEK_CUR)
450 */
451 #if defined(__GLIBC__)
452 if (i < (off_t)t->n) {
453 #endif
454 /* zero */
455 T_EXPECT_POSIX_ZERO(fseeko(fp, (off_t)0, SEEK_CUR), NULL);
456 T_EXPECT_EQ(ftello(fp), len, NULL);
457
458 /* posive */
459 for (i = (off_t)1; i <= rest; ++i) {
460 T_EXPECT_POSIX_ZERO(fseeko(fp, (off_t)1, SEEK_CUR), NULL);
461 T_EXPECT_EQ(ftello(fp), len + i, NULL);
462 }
463
464 /* positive + OOB */
465 T_EXPECT_EQ(fseeko(fp, (off_t)1, SEEK_CUR), -1, NULL);
466 T_EXPECT_EQ(ftello(fp), (off_t)t->n, NULL);
467
468 /* negative */
469 for (i = (off_t)1; i <= (off_t)t->n; ++i) {
470 T_EXPECT_POSIX_ZERO(fseeko(fp, (off_t)-1, SEEK_CUR), NULL);
471 T_EXPECT_EQ(ftello(fp), (off_t)t->n - i, NULL);
472 }
473
474 /* negative + OOB */
475 T_EXPECT_EQ(fseeko(fp, (off_t)-1, SEEK_CUR), -1, NULL);
476 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
477
478 #if defined(__GLIBC__)
479 }
480 #endif
481 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
482 }
483 }
484 }
485
486 #if 0
487 T_DECL(netbsd_fmemopen_test12, "")
488 {
489 struct testcase *t;
490 off_t len, rest, i;
491 const char **p;
492 char buf[BUFSIZ];
493 FILE *fp;
494
495 /* test fmemopen_seek(SEEK_END) */
496 for (t = &testcases[0]; t->s != NULL; ++t) {
497 len = (off_t)strnlen(t->s, t->n);
498 rest = t->n - len;
499 for (p = &mode_r[0]; *p != NULL; ++p) {
500
501 memcpy(buf, t->s, t->n);
502 fp = fmemopen(&buf[0], t->n, *p);
503 T_EXPECT_NOTNULL(fp, NULL);
504
505 /*
506 * test fmemopen_seek(SEEK_END)
507 */
508 #if !defined(__GLIBC__)
509 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
510
511 /* zero */
512 T_EXPECT_POSIX_ZERO(fseeko(fp, (off_t)0, SEEK_END), NULL);
513 T_EXPECT_EQ(ftello(fp), len, NULL);
514
515 /* positive + OOB */
516 T_EXPECT_EQ(fseeko(fp, rest + 1, SEEK_END), -1, NULL);
517 T_EXPECT_EQ(ftello(fp), len, NULL);
518
519 /* negative + OOB */
520 T_EXPECT_EQ(fseeko(fp, -(len + 1), SEEK_END), -1, NULL);
521 T_EXPECT_EQ(ftello(fp), len, NULL);
522
523 /* positive */
524 for (i = 1; i <= rest; ++i) {
525 T_EXPECT_POSIX_ZERO(fseeko(fp, i, SEEK_END), NULL);
526 T_EXPECT_EQ(ftello(fp), len + i, NULL);
527 }
528
529 /* negative */
530 for (i = 1; i < len; ++i) {
531 T_EXPECT_POSIX_ZERO(fseeko(fp, -i, SEEK_END), NULL);
532 T_EXPECT_EQ(ftello(fp), len - i, NULL);
533 }
534 #endif
535 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
536 }
537 }
538 }
539 #endif // 0
540
541 T_DECL(netbsd_fmemopen_test13, "")
542 {
543 struct testcase *t;
544 const char **p;
545 char buf[BUFSIZ];
546 FILE *fp;
547
548 /* test fmemopen_seek(SEEK_END) */
549 for (t = &testcases[0]; t->s != NULL; ++t) {
550 for (p = &mode_w[0]; *p != NULL; ++p) {
551
552 memcpy(buf, t->s, t->n);
553 fp = fmemopen(&buf[0], (size_t)t->n, *p);
554 T_EXPECT_NOTNULL(fp, NULL);
555 /*
556 * test fmemopen_seek(SEEK_END)
557 */
558 #if !defined(__GLIBC__)
559 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
560 T_EXPECT_EQ(buf[0], '\0', NULL);
561
562 /* zero */
563 T_EXPECT_POSIX_ZERO(fseeko(fp, (off_t)0, SEEK_END), NULL);
564 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
565
566 /* positive + OOB */
567 T_EXPECT_EQ(fseeko(fp, (off_t)t->n + 1, SEEK_END), -1, NULL);
568 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
569
570 /* negative + OOB */
571 T_EXPECT_EQ(fseeko(fp, -1, SEEK_END), -1, NULL);
572 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
573 #endif
574
575 #if 0
576 /* positive */
577 for (int i = 1; i <= t->n; ++i) {
578 T_EXPECT_POSIX_ZERO(fseeko(fp, i, SEEK_END), NULL);
579 T_EXPECT_EQ(ftello(fp), i, NULL);
580 }
581 #endif
582 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
583 }
584 }
585 }
586
587 T_DECL(netbsd_fmemopen_test14, "")
588 {
589 struct testcase *t;
590 off_t len, rest, i;
591 const char **p;
592 char buf[BUFSIZ];
593 FILE *fp;
594
595 /* test fmemopen_seek(SEEK_END) */
596 for (t = &testcases[0]; t->s != NULL; ++t) {
597 len = (off_t)strnlen(t->s, (size_t)t->n);
598 rest = (off_t)t->n - len;
599 for (p = &mode_a[0]; *p != NULL; ++p) {
600
601 memcpy(buf, t->s, t->n);
602 fp = fmemopen(&buf[0], (size_t)t->n, *p);
603 T_EXPECT_NOTNULL(fp, NULL);
604 /*
605 * test fmemopen_seek(SEEK_END)
606 */
607 #if !defined(__GLIBC__)
608 T_EXPECT_EQ(ftello(fp), len, NULL);
609
610 /* zero */
611 T_EXPECT_POSIX_ZERO(fseeko(fp, 0, SEEK_END), NULL);
612 T_EXPECT_EQ(ftello(fp), len, NULL);
613
614 /* positive + OOB */
615 T_EXPECT_EQ(fseeko(fp, rest + 1, SEEK_END), -1, NULL);
616 T_EXPECT_EQ(ftello(fp), len, NULL);
617
618 /* negative + OOB */
619 T_EXPECT_EQ(fseeko(fp, -(len + 1), SEEK_END), -1, NULL);
620 T_EXPECT_EQ(ftello(fp), len, NULL);
621
622 #if 0
623 /* positive */
624 for (i = 1; i <= rest; ++i) {
625 T_EXPECT_POSIX_ZERO(fseeko(fp, i, SEEK_END), NULL);
626 T_EXPECT_EQ(ftello(fp), len + i, NULL);
627 }
628 #endif
629
630 /* negative */
631 for (i = 1; i < len; ++i) {
632 T_EXPECT_POSIX_ZERO(fseeko(fp, -i, SEEK_END), NULL);
633 T_EXPECT_EQ(ftello(fp), len - i, NULL);
634 }
635 #endif
636 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
637 }
638 }
639 }
640
641 #if 0
642
643 static const char *mode_rw1[] = {
644 "r", "rb", "r+", "rb+", "r+b",
645 "w+", "wb+",
646 NULL
647 };
648
649 /* test15 - 18:
650 * When a stream open for writing is flushed or closed, a null byte is written
651 * at the current position or at the end of the buffer, depending on the size
652 * of the contents.
653 */
654
655 T_DECL(netbsd_fmemopen_test15, "")
656 {
657 struct testcase *t;
658 const char **p;
659 char buf0[BUFSIZ];
660 FILE *fp;
661 int i;
662
663 for (t = &testcases[0]; t->s != NULL; ++t) {
664 for (p = &mode_rw1[0]; *p != NULL; ++p) {
665
666 memcpy(&buf0[0], t->s, t->n);
667 fp = fmemopen(&buf0[0], t->n, *p);
668 T_EXPECT_NOTNULL(fp, NULL);
669 /*
670 * test fmemopen_read + fgetc(3)
671 */
672 for (i = 0; i < t->n; ++i) {
673 T_EXPECT_EQ(ftello(fp), (off_t)i, NULL);
674 T_EXPECT_EQ(fgetc(fp), buf0[i], NULL);
675 T_EXPECT_EQ(feof(fp), 0, NULL);
676 T_EXPECT_EQ(ftello(fp), (off_t)i + 1, NULL);
677 }
678 T_EXPECT_EQ(fgetc(fp), EOF, NULL);
679 T_EXPECT_NE(feof(fp), 0, NULL);
680 T_EXPECT_EQ(ftello(fp), (off_t)t->n, NULL);
681 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
682 }
683 }
684 }
685
686 T_DECL(netbsd_fmemopen_test16, "")
687 {
688 struct testcase *t;
689 const char **p;
690 char buf0[BUFSIZ], buf1[BUFSIZ];
691 FILE *fp;
692
693 for (t = &testcases[0]; t->s != NULL; ++t) {
694 for (p = &mode_rw1[0]; *p != NULL; ++p) {
695
696 memcpy(&buf0[0], t->s, t->n);
697 buf1[t->n] = 0x1;
698 fp = fmemopen(&buf0[0], t->n, *p);
699 T_EXPECT_NOTNULL(fp, NULL);
700 /*
701 * test fmemopen_read + fread(4)
702 */
703 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
704 T_EXPECT_EQ(fread(&buf1[0], 1, sizeof(buf1), fp), (size_t)t->n, NULL);
705 T_EXPECT_NE(feof(fp), 0, NULL);
706 T_EXPECT_EQ(memcmp(&buf0[0], &buf1[0], t->n), 0, NULL);
707 T_EXPECT_EQ((unsigned char)buf1[t->n], 0x1, NULL);
708
709 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
710 }
711 }
712 }
713
714 const char *mode_a1[] = { "a+", "ab+", NULL };
715
716 T_DECL(netbsd_fmemopen_test17, "")
717 {
718 struct testcase *t;
719 size_t len;
720 int i;
721 const char **p;
722 char buf[BUFSIZ];
723 FILE *fp;
724
725 for (t = &testcases[0]; t->s != NULL; ++t) {
726 len = strnlen(t->s, t->n);
727 for (p = &mode_a1[0]; *p != NULL; ++p) {
728
729 memcpy(&buf[0], t->s, t->n);
730 fp = fmemopen(&buf[0], t->n, *p);
731 T_EXPECT_NOTNULL(fp, NULL);
732 /*
733 * test fmemopen_read + fgetc(3)
734 */
735 #if defined(__GLIBC__)
736 if (i < t->n) {
737 #endif
738 for (i = len; i < t->n; ++i) {
739 T_EXPECT_EQ(ftello(fp), (off_t)i, NULL);
740 T_EXPECT_EQ(fgetc(fp), buf[i], NULL);
741 T_EXPECT_EQ(feof(fp), 0, NULL);
742 T_EXPECT_EQ(ftello(fp), (off_t)i + 1, NULL);
743 }
744 T_EXPECT_EQ(fgetc(fp), EOF, NULL);
745 T_EXPECT_NE(feof(fp), 0, NULL);
746 T_EXPECT_EQ(ftello(fp), (off_t)t->n, NULL);
747 rewind(fp);
748 for (i = 0; i < t->n; ++i) {
749 T_EXPECT_EQ(ftello(fp), (off_t)i, NULL);
750 T_EXPECT_EQ(fgetc(fp), buf[i], NULL);
751 T_EXPECT_EQ(feof(fp), 0, NULL);
752 T_EXPECT_EQ(ftello(fp), (off_t)i + 1, NULL);
753 }
754 T_EXPECT_EQ(fgetc(fp), EOF, NULL);
755 T_EXPECT_NE(feof(fp), 0, NULL);
756 T_EXPECT_EQ(ftello(fp), (off_t)t->n, NULL);
757 #if defined(__GLIBC__)
758 }
759 #endif
760 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
761 }
762 }
763 }
764
765 T_DECL(netbsd_fmemopen_test18, "")
766 {
767 struct testcase *t;
768 size_t len;
769 const char **p;
770 char buf0[BUFSIZ], buf1[BUFSIZ];
771 FILE *fp;
772
773 for (t = &testcases[0]; t->s != NULL; ++t) {
774 len = strnlen(t->s, t->n);
775 for (p = &mode_a1[0]; *p != NULL; ++p) {
776
777 memcpy(&buf0[0], t->s, t->n);
778 buf1[t->n - len] = 0x1;
779 fp = fmemopen(&buf0[0], t->n, *p);
780 T_EXPECT_NOTNULL(fp, NULL);
781 /*
782 * test fmemopen_read + fread(3)
783 */
784 #if defined(__GLIBC__)
785 if (i < t->n) {
786 #endif
787 T_EXPECT_EQ(ftello(fp), (off_t)len, NULL);
788 T_EXPECT_EQ(fread(&buf1[0], 1, sizeof(buf1), fp)
789 , t->n - len, NULL);
790 T_EXPECT_NE(feof(fp), 0, NULL);
791 T_EXPECT_FALSE(memcmp(&buf0[len], &buf1[0], t->n - len));
792 T_EXPECT_EQ((unsigned char)buf1[t->n - len], 0x1, NULL);
793 rewind(fp);
794 buf1[t->n] = 0x1;
795 T_EXPECT_EQ(ftello(fp), (off_t)0, NULL);
796 T_EXPECT_EQ(fread(&buf1[0], 1, sizeof(buf1), fp)
797 , (size_t)t->n, NULL);
798 T_EXPECT_NE(feof(fp), 0, NULL);
799 T_EXPECT_FALSE(memcmp(&buf0[0], &buf1[0], t->n));
800 T_EXPECT_EQ((unsigned char)buf1[t->n], 0x1, NULL);
801 #if defined(__GLIBC__)
802 }
803 #endif
804 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
805 }
806 }
807 }
808
809 /*
810 * test19 - test22:
811 * If a stream open for update is flushed or closed and the last write has
812 * advanced the current buffer size, a null byte is written at the end of the
813 * buffer if it fits.
814 */
815
816 const char *mode_rw2[] = {
817 "r+", "rb+", "r+b",
818 "w", "wb", "w+", "wb+", "w+b",
819 NULL
820 };
821
822 T_DECL(netbsd_fmemopen_test19, "")
823 {
824 struct testcase *t;
825 int i;
826 const char **p;
827 char buf[BUFSIZ];
828 FILE *fp;
829
830 for (t = &testcases[0]; t->s != NULL; ++t) {
831 for (p = &mode_rw2[0]; *p != NULL; ++p) {
832
833 memcpy(&buf[0], t->s, t->n);
834 buf[t->n] = 0x1;
835 fp = fmemopen(&buf[0], t->n + 1, *p);
836 T_EXPECT_NOTNULL(fp, NULL);
837 setbuf(fp, NULL);
838 /*
839 * test fmemopen_write + fputc(3)
840 */
841 for (i = 0; i < t->n; ++i) {
842 T_EXPECT_EQ(ftello(fp), (off_t)i, NULL);
843 T_EXPECT_EQ(fputc(t->s[i], fp), t->s[i], NULL);
844 T_EXPECT_EQ(buf[i], t->s[i], NULL);
845 T_EXPECT_EQ(ftello(fp), (off_t)i + 1, NULL);
846 T_EXPECT_EQ(buf[i], t->s[i], NULL);
847 #if !defined(__GLIBC__)
848 T_EXPECT_EQ(buf[i + 1], '\0', NULL);
849 #endif
850 }
851
852 /* don't accept non nul character at end of buffer */
853 T_EXPECT_EQ(fputc(0x1, fp), EOF, NULL);
854 T_EXPECT_EQ(ftello(fp), (off_t)t->n, NULL);
855 T_EXPECT_EQ(feof(fp), 0, NULL);
856
857 /* accept nul character at end of buffer */
858 T_EXPECT_EQ(fputc('\0', fp), '\0', NULL);
859 T_EXPECT_EQ(ftello(fp), (off_t)t->n + 1, NULL);
860 T_EXPECT_EQ(feof(fp), 0, NULL);
861
862 /* reach EOF */
863 T_EXPECT_EQ(fputc('\0', fp), EOF, NULL);
864 T_EXPECT_EQ(ftello(fp), (off_t)t->n + 1, NULL);
865
866 /* compare */
867 T_EXPECT_EQ(memcmp(&buf[0], t->s, t->n), 0, NULL);
868 T_EXPECT_EQ(buf[t->n], '\0', NULL);
869
870 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
871 }
872 }
873 }
874
875 T_DECL(netbsd_fmemopen_test20, "")
876 {
877 struct testcase *t;
878 const char **p;
879 char buf[BUFSIZ];
880 FILE *fp;
881
882 for (t = &testcases[0]; t->s != NULL; ++t) {
883 for (p = &mode_rw2[0]; *p != NULL; ++p) {
884
885 memcpy(&buf[0], t->s, t->n);
886 buf[t->n] = 0x1;
887 fp = fmemopen(&buf[0], t->n + 1, *p);
888 T_EXPECT_NOTNULL(fp, NULL);
889 setbuf(fp, NULL);
890 T_EXPECT_EQ(fwrite(t->s, 1, t->n, fp), (size_t)t->n, NULL);
891 /*
892 * test fmemopen_write + fwrite(3)
893 */
894 #if !defined(__GLIBC__)
895 T_EXPECT_EQ(buf[t->n], '\0', NULL);
896
897 /* don't accept non nul character at end of buffer */
898 T_EXPECT_EQ(fwrite("\x1", 1, 1, fp), 0, NULL);
899 T_EXPECT_EQ(ftello(fp), (off_t)t->n, NULL);
900 T_EXPECT_EQ(feof(fp), 0, NULL);
901 #endif
902
903 /* accept nul character at end of buffer */
904 T_EXPECT_EQ(fwrite("\x0", 1, 1, fp), 1, NULL);
905 T_EXPECT_EQ(ftello(fp), (off_t)t->n + 1, NULL);
906 T_EXPECT_EQ(feof(fp), 0, NULL);
907
908 /* reach EOF */
909 T_EXPECT_EQ(fputc('\0', fp), EOF, NULL);
910 T_EXPECT_EQ(ftello(fp), (off_t)t->n + 1, NULL);
911
912 /* compare */
913 T_EXPECT_EQ(memcmp(&buf[0], t->s, t->n), 0, NULL);
914 T_EXPECT_EQ(buf[t->n], '\0', NULL);
915
916 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
917 }
918 }
919 }
920
921 T_DECL(netbsd_fmemopen_test21, "")
922 {
923 struct testcase *t;
924 int len, i;
925 const char **p;
926 char buf[BUFSIZ];
927 FILE *fp;
928
929 for (t = &testcases[0]; t->s != NULL; ++t) {
930 len = strnlen(t->s, t->n);
931 for (p = &mode_a[0]; *p != NULL; ++p) {
932 memcpy(&buf[0], t->s, t->n);
933 fp = fmemopen(&buf[0], t->n, *p);
934 T_EXPECT_NOTNULL(fp, NULL);
935 setbuf(fp, NULL);
936 /*
937 * test fmemopen_write + fputc(3)
938 */
939 if (len < t->n) {
940 for (i = len; i < t->n - 1; ++i) {
941 T_EXPECT_EQ(ftello(fp), (off_t)i, NULL);
942 T_EXPECT_EQ(fputc(t->s[i - len], fp)
943 , t->s[i - len], NULL);
944 T_EXPECT_EQ(buf[i], t->s[i - len], NULL);
945 T_EXPECT_EQ(ftello(fp), (off_t)i + 1, NULL);
946 #if !defined(__GLIBC__)
947 T_EXPECT_EQ(buf[i + 1], '\0', NULL);
948 #endif
949 }
950
951 /* don't accept non nul character at end of buffer */
952 T_EXPECT_EQ(ftello(fp), (off_t)t->n - 1, NULL);
953 T_EXPECT_EQ(fputc(0x1, fp), EOF, NULL);
954 T_EXPECT_EQ(ftello(fp), (off_t)t->n - 1, NULL);
955
956 /* accept nul character at end of buffer */
957 T_EXPECT_EQ(ftello(fp), (off_t)t->n - 1, NULL);
958 T_EXPECT_EQ(fputc('\0', fp), '\0', NULL);
959 T_EXPECT_EQ(ftello(fp), (off_t)t->n, NULL);
960 }
961
962 /* reach EOF */
963 T_EXPECT_EQ(ftello(fp), (off_t)t->n, NULL);
964 T_EXPECT_EQ(fputc('\0', fp), EOF, NULL);
965 T_EXPECT_EQ(ftello(fp), (off_t)t->n, NULL);
966
967 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
968 }
969 }
970 }
971
972 T_DECL(netbsd_fmemopen_test22, "")
973 {
974 struct testcase *t0, *t1;
975 size_t len0, len1, nleft;
976 const char **p;
977 char buf[BUFSIZ];
978 FILE *fp;
979
980 for (t0 = &testcases[0]; t0->s != NULL; ++t0) {
981 len0 = strnlen(t0->s, t0->n);
982 for (t1 = &testcases[0]; t1->s != NULL; ++t1) {
983 len1 = strnlen(t1->s, t1->n);
984 for (p = &mode_a[0]; *p != NULL; ++p) {
985
986 memcpy(&buf[0], t0->s, t0->n);
987 fp = fmemopen(&buf[0], t0->n, *p);
988 T_EXPECT_NOTNULL(fp, NULL);
989 setbuf(fp, NULL);
990 /*
991 * test fmemopen_write + fwrite(3)
992 */
993 nleft = t0->n - len0;
994 #if !defined(__GLIBC__)
995 if (nleft == 0 || len1 == nleft - 1) {
996 T_EXPECT_EQ(fwrite(t1->s, 1, t1->n, fp)
997 , nleft, NULL);
998 T_EXPECT_EQ(ftell(fp), t1->n, NULL);
999 } else {
1000 T_EXPECT_EQ(fwrite(t1->s, 1, t1->n, fp)
1001 , nleft - 1, NULL);
1002 T_EXPECT_EQ(ftell(fp), t1->n - 1, NULL);
1003 }
1004 #endif
1005 T_EXPECT_POSIX_ZERO(fclose(fp), NULL);
1006 }
1007 }
1008 }
1009 }
1010 #endif //0