t_fmemopen.c revision 1.1 1 /* $NetBSD: t_fmemopen.c,v 1.1 2010/09/24 09:21:53 tnozaki 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 #if defined(__NetBSD__)
31 #include <atf-c.h>
32 #else
33 #if defined(__linux__)
34 #define _GNU_SOURCE
35 #include <features.h>
36 #endif
37 #include <assert.h>
38 #include <stdio.h>
39 #define ATF_TC(arg0) static void arg0##_head(void)
40 #define ATF_TC_HEAD(arg0, arg1) static void arg0##_head()
41 #define atf_tc_set_md_var(arg0, arg1, ...) do { \
42 printf(__VA_ARGS__); \
43 puts(""); \
44 } while (/*CONSTCOND*/0)
45 #define ATF_TC_BODY(arg0, arg1) static void arg0##_body()
46 #define ATF_CHECK(arg0) assert(arg0)
47 #define ATF_TP_ADD_TCS(arg0) int main(void)
48 #define ATF_TP_ADD_TC(arg0, arg1) arg1##_head(); arg1##_body()
49 #define atf_no_error() 0
50 #endif
51
52 #include <errno.h>
53 #include <stdio.h>
54 #include <limits.h>
55 #include <stdlib.h>
56 #include <string.h>
57
58 const char *mode_rwa[] = {
59 "r", "rb", "r+", "rb+", "r+b",
60 "w", "wb", "w+", "wb+", "w+b",
61 "a", "ab", "a+", "ab+", "a+b",
62 NULL
63 };
64
65 const char *mode_r[] = { "r", "rb", "r+", "rb+", "r+b", NULL };
66 const char *mode_w[] = { "w", "wb", "w+", "wb+", "w+b", NULL };
67 const char *mode_a[] = { "a", "ab", "a+", "ab+", "a+b", NULL };
68
69 struct testcase {
70 const char *s;
71 size_t n;
72 } testcases[] = {
73 #define TESTSTR(s) { s, sizeof(s)-1 }
74 TESTSTR("\0he quick brown fox jumps over the lazy dog"),
75 TESTSTR("T\0e quick brown fox jumps over the lazy dog"),
76 TESTSTR("Th\0 quick brown fox jumps over the lazy dog"),
77 TESTSTR("The\0quick brown fox jumps over the lazy dog"),
78 TESTSTR("The \0uick brown fox jumps over the lazy dog"),
79 TESTSTR("The q\0ick brown fox jumps over the lazy dog"),
80 TESTSTR("The qu\0ck brown fox jumps over the lazy dog"),
81 TESTSTR("The qui\0k brown fox jumps over the lazy dog"),
82 TESTSTR("The quic\0 brown fox jumps over the lazy dog"),
83 TESTSTR("The quick\0brown fox jumps over the lazy dog"),
84 TESTSTR("The quick \0rown fox jumps over the lazy dog"),
85 TESTSTR("The quick b\0own fox jumps over the lazy dog"),
86 TESTSTR("The quick br\0wn fox jumps over the lazy dog"),
87 TESTSTR("The quick bro\0n fox jumps over the lazy dog"),
88 TESTSTR("The quick brow\0 fox jumps over the lazy dog"),
89 TESTSTR("The quick brown\0fox jumps over the lazy dog"),
90 TESTSTR("The quick brown \0ox jumps over the lazy dog"),
91 TESTSTR("The quick brown f\0x jumps over the lazy dog"),
92 TESTSTR("The quick brown fo\0 jumps over the lazy dog"),
93 TESTSTR("The quick brown fox\0jumps over the lazy dog"),
94 TESTSTR("The quick brown fox \0umps over the lazy dog"),
95 TESTSTR("The quick brown fox j\0mps over the lazy dog"),
96 TESTSTR("The quick brown fox ju\0ps over the lazy dog"),
97 TESTSTR("The quick brown fox jum\0s over the lazy dog"),
98 TESTSTR("The quick brown fox jump\0 over the lazy dog"),
99 TESTSTR("The quick brown fox jumps\0over the lazy dog"),
100 TESTSTR("The quick brown fox jumps \0ver the lazy dog"),
101 TESTSTR("The quick brown fox jumps o\0er the lazy dog"),
102 TESTSTR("The quick brown fox jumps ov\0r the lazy dog"),
103 TESTSTR("The quick brown fox jumps ove\0 the lazy dog"),
104 TESTSTR("The quick brown fox jumps over\0the lazy dog"),
105 TESTSTR("The quick brown fox jumps over \0he lazy dog"),
106 TESTSTR("The quick brown fox jumps over t\0e lazy dog"),
107 TESTSTR("The quick brown fox jumps over th\0 lazy dog"),
108 TESTSTR("The quick brown fox jumps over the\0lazy dog"),
109 TESTSTR("The quick brown fox jumps over the \0azy dog"),
110 TESTSTR("The quick brown fox jumps over the l\0zy dog"),
111 TESTSTR("The quick brown fox jumps over the la\0y dog"),
112 TESTSTR("The quick brown fox jumps over the laz\0 dog"),
113 TESTSTR("The quick brown fox jumps over the lazy\0dog"),
114 TESTSTR("The quick brown fox jumps over the lazy \0og"),
115 TESTSTR("The quick brown fox jumps over the lazy d\0g"),
116 TESTSTR("The quick brown fox jumps over the lazy do\0"),
117 TESTSTR("The quick brown fox jumps over the lazy dog"),
118 { NULL, 0 },
119 };
120
121 ATF_TC(test00);
122 ATF_TC_HEAD(test00, tc)
123 {
124 atf_tc_set_md_var(tc, "descr", "test00");
125 }
126 ATF_TC_BODY(test00, tc)
127 {
128 const char **p;
129 char buf[BUFSIZ];
130 FILE *fp;
131
132 for (p = &mode_rwa[0]; *p != NULL; ++p) {
133 fp = fmemopen(&buf[0], sizeof(buf), *p);
134 /*
135 * Upon successful completion, fmemopen() shall return a pointer to the
136 * object controlling the stream.
137 */
138 ATF_CHECK(fp != NULL);
139
140 ATF_CHECK(fclose(fp) == 0);
141 }
142 }
143
144 ATF_TC(test01);
145 ATF_TC_HEAD(test01, tc)
146 {
147 atf_tc_set_md_var(tc, "descr", "test01");
148 }
149 ATF_TC_BODY(test01, tc)
150 {
151 const char **p;
152 const char *mode[] = {
153 "r+", "rb+", "r+b",
154 "w+", "wb+", "w+b",
155 "a+", "ab+", "a+b",
156 NULL
157 };
158 FILE *fp;
159
160 for (p = &mode[0]; *p != NULL; ++p) {
161 /*
162 * If a null pointer is specified as the buf argument, fmemopen() shall
163 * allocate size bytes of memory as if by a call to malloc().
164 */
165 fp = fmemopen(NULL, BUFSIZ, *p);
166 ATF_CHECK(fp != NULL);
167
168 /*
169 * If buf is a null pointer, the initial position shall always be set
170 * to the beginning of the buffer.
171 */
172 ATF_CHECK(ftello(fp) == (off_t)0);
173
174 ATF_CHECK(fclose(fp) == 0);
175 }
176 }
177
178 ATF_TC(test02);
179 ATF_TC_HEAD(test02, tc)
180 {
181 atf_tc_set_md_var(tc, "descr", "test02");
182 }
183 ATF_TC_BODY(test02, tc)
184 {
185 const char **p;
186 char buf[BUFSIZ];
187 FILE *fp;
188
189 for (p = &mode_r[0]; *p != NULL; ++p) {
190
191 memset(&buf[0], 0x1, sizeof(buf));
192 fp = fmemopen(&buf[0], sizeof(buf), *p);
193 ATF_CHECK(fp != NULL);
194
195 /*
196 * This position is initially set to either the beginning of the buffer
197 * (for r and w modes)
198 */
199 ATF_CHECK((unsigned char)buf[0] == 0x1);
200 ATF_CHECK(ftello(fp) == (off_t)0);
201
202 /*
203 * The stream also maintains the size of the current buffer contents.
204 * For modes r and r+ the size is set to the value given by the size argument.
205 */
206 #if !defined(__GLIBC__)
207 ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
208 ATF_CHECK(ftello(fp) == (off_t)sizeof(buf));
209 #endif
210 ATF_CHECK(fclose(fp) == 0);
211 }
212 }
213
214 ATF_TC(test03);
215 ATF_TC_HEAD(test03, tc)
216 {
217 atf_tc_set_md_var(tc, "descr", "test03");
218 }
219 ATF_TC_BODY(test03, tc)
220 {
221 const char **p;
222 char buf[BUFSIZ];
223 FILE *fp;
224
225 for (p = &mode_w[0]; *p != NULL; ++p) {
226
227 memset(&buf[0], 0x1, sizeof(buf));
228 fp = fmemopen(&buf[0], sizeof(buf), *p);
229 ATF_CHECK(fp != NULL);
230
231 /*
232 * This position is initially set to either the beginning of the buffer
233 * (for r and w modes)
234 */
235 ATF_CHECK(buf[0] == '\0');
236 ATF_CHECK(ftello(fp) == (off_t)0);
237
238 /*
239 * For modes w and w+ the initial size is zero
240 */
241 ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
242 ATF_CHECK(ftello(fp) == (off_t)0);
243
244 ATF_CHECK(fclose(fp) == 0);
245 }
246 }
247
248 ATF_TC(test04);
249 ATF_TC_HEAD(test04, tc)
250 {
251 atf_tc_set_md_var(tc, "descr", "test04");
252 }
253 ATF_TC_BODY(test04, tc)
254 {
255 const char **p;
256 char buf[BUFSIZ];
257 FILE *fp;
258
259 /*
260 * or to the first null byte in the buffer (for a modes)
261 */
262 for (p = &mode_a[0]; *p != NULL; ++p) {
263
264 memset(&buf[0], 0x1, sizeof(buf));
265 fp = fmemopen(&buf[0], sizeof(buf), *p);
266 ATF_CHECK(fp != NULL);
267
268 ATF_CHECK((unsigned char)buf[0] == 0x1);
269
270 /* If no null byte is found in append mode,
271 * the initial position is set to one byte after the end of the buffer.
272 */
273 #if !defined(__GLIBC__)
274 ATF_CHECK(ftello(fp) == (off_t)sizeof(buf));
275 #endif
276
277 /*
278 * and for modes a and a+ the initial size is either the position of the
279 * first null byte in the buffer or the value of the size argument
280 * if no null byte is found.
281 */
282 #if !defined(__GLIBC__)
283 ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
284 ATF_CHECK(ftello(fp) == (off_t)sizeof(buf));
285 #endif
286
287 ATF_CHECK(fclose(fp) == 0);
288 }
289 }
290
291 ATF_TC(test05);
292 ATF_TC_HEAD(test05, tc)
293 {
294 atf_tc_set_md_var(tc, "descr", "test05");
295 }
296 ATF_TC_BODY(test05, tc)
297 {
298 const char **p;
299 FILE *fp;
300 char buf[BUFSIZ];
301
302 for (p = &mode_rwa[0]; *p != NULL; ++p) {
303 /*
304 * Otherwise, a null pointer shall be returned, and errno shall be set
305 * to indicate the error.
306 */
307 errno = 0;
308 fp = fmemopen(NULL, (size_t)0, *p);
309 ATF_CHECK(fp == NULL);
310 ATF_CHECK(errno == EINVAL);
311
312 errno = 0;
313 fp = fmemopen((void *)&buf[0], 0, *p);
314 ATF_CHECK(fp == NULL);
315 ATF_CHECK(errno == EINVAL);
316 }
317 }
318
319 ATF_TC(test06);
320 ATF_TC_HEAD(test06, tc)
321 {
322 atf_tc_set_md_var(tc, "descr", "test06");
323 }
324 ATF_TC_BODY(test06, tc)
325 {
326 const char **p;
327 const char *mode[] = { "", " ", "???", NULL };
328 FILE *fp;
329
330 for (p = &mode[0]; *p != NULL; ++p) {
331 /*
332 * The value of the mode argument is not valid.
333 */
334 fp = fmemopen(NULL, 1, *p);
335 ATF_CHECK(fp == NULL);
336 ATF_CHECK(errno == EINVAL);
337 }
338 }
339
340 ATF_TC(test07);
341 ATF_TC_HEAD(test07, tc)
342 {
343 atf_tc_set_md_var(tc, "descr", "test07");
344 }
345 ATF_TC_BODY(test07, tc)
346 {
347 #if !defined(__GLIBC__)
348 const char **p;
349 const char *mode[] = {
350 "r", "rb",
351 "w", "wb",
352 "a", "ab",
353 NULL
354 };
355 FILE *fp;
356
357 for (p = &mode[0]; *p != NULL; ++p) {
358 /*
359 * Because this feature is only useful when the stream is opened for updating
360 * (because there is no way to get a pointer to the buffer) the fmemopen()
361 * call may fail if the mode argument does not include a '+' .
362 */
363 errno = 0;
364 fp = fmemopen(NULL, 1, *p);
365 ATF_CHECK(fp == NULL);
366 ATF_CHECK(errno == EINVAL);
367 }
368 #endif
369 }
370
371 ATF_TC(test08);
372 ATF_TC_HEAD(test08, tc)
373 {
374 atf_tc_set_md_var(tc, "descr", "test08");
375 }
376 ATF_TC_BODY(test08, tc)
377 {
378 #if !defined(__GLIBC__)
379 const char **p;
380 const char *mode[] = {
381 "r+", "rb+", "r+b",
382 "w+", "wb+", "w+b",
383 "a+", "ab+", "a+b",
384 NULL
385 };
386 FILE *fp;
387
388 for (p = &mode[0]; *p != NULL; ++p) {
389 /*
390 * The buf argument is a null pointer and the allocation of a buffer of
391 * length size has failed.
392 */
393 fp = fmemopen(NULL, SIZE_MAX, *p);
394 ATF_CHECK(fp == NULL);
395 ATF_CHECK(errno == ENOMEM);
396 }
397 #endif
398 }
399
400 /*
401 * test09 - test14:
402 * An attempt to seek a memory buffer stream to a negative position or to a
403 * position larger than the buffer size given in the size argument shall fail.
404 */
405
406 ATF_TC(test09);
407 ATF_TC_HEAD(test09, tc)
408 {
409 atf_tc_set_md_var(tc, "descr", "test09");
410 }
411 ATF_TC_BODY(test09, tc)
412 {
413 struct testcase *t;
414 const char **p;
415 char buf[BUFSIZ];
416 FILE *fp;
417 off_t i;
418
419 for (t = &testcases[0]; t->s != NULL; ++t) {
420 for (p = &mode_rwa[0]; *p != NULL; ++p) {
421
422 memcpy(&buf[0], t->s, t->n);
423 fp = fmemopen(&buf[0], t->n, *p);
424 ATF_CHECK(fp != NULL);
425
426 /*
427 * test fmemopen_seek(SEEK_SET)
428 */
429 /* zero */
430 ATF_CHECK(fseeko(fp, (off_t)0, SEEK_SET) == 0);
431 ATF_CHECK(ftello(fp) == (off_t)0);
432
433 /* positive */
434 for (i = (off_t)1; i <= (off_t)t->n; ++i) {
435 ATF_CHECK(fseeko(fp, i, SEEK_SET) == 0);
436 ATF_CHECK(ftello(fp) == i);
437 }
438 /* positive + OOB */
439 ATF_CHECK(fseeko(fp, t->n + 1, SEEK_SET) == -1);
440 ATF_CHECK(ftello(fp) == t->n);
441
442 /* negative + OOB */
443 ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_SET) == -1);
444 ATF_CHECK(ftello(fp) == t->n);
445
446 ATF_CHECK(fclose(fp) == 0);
447 }
448 }
449 }
450
451 const char *mode_rw[] = {
452 "r", "rb", "r+", "rb+", "r+b",
453 "w", "wb", "w+", "wb+", "w+b",
454 NULL
455 };
456
457 ATF_TC(test10);
458 ATF_TC_HEAD(test10, tc)
459 {
460 atf_tc_set_md_var(tc, "descr", "test10");
461 }
462 ATF_TC_BODY(test10, tc)
463 {
464 struct testcase *t;
465 off_t len, i;
466 const char **p;
467 char buf[BUFSIZ];
468 FILE *fp;
469
470 for (t = &testcases[0]; t->s != NULL; ++t) {
471 len = (off_t)strnlen(t->s, t->n);
472 for (p = &mode_rw[0]; *p != NULL; ++p) {
473
474 memcpy(&buf[0], t->s, t->n);
475 fp = fmemopen(&buf[0], t->n, *p);
476 ATF_CHECK(fp != NULL);
477
478 /*
479 * test fmemopen_seek(SEEK_CUR)
480 */
481 ATF_CHECK(ftello(fp) == (off_t)0);
482
483 /* zero */
484 ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0);
485 ATF_CHECK(ftello(fp) == (off_t)0);
486
487 /* negative & OOB */
488 ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1);
489 ATF_CHECK(ftello(fp) == (off_t)0);
490
491 /* positive */
492 for (i = 0; i < (off_t)t->n; ++i) {
493 ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0);
494 ATF_CHECK(ftello(fp) == i + 1);
495 }
496
497 /* positive & OOB */
498 ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1);
499 ATF_CHECK(ftello(fp) == (off_t)t->n);
500
501 ATF_CHECK(fclose(fp) == 0);
502 }
503 }
504 }
505
506 ATF_TC(test11);
507 ATF_TC_HEAD(test11, tc)
508 {
509 atf_tc_set_md_var(tc, "descr", "test11");
510 }
511 ATF_TC_BODY(test11, tc)
512 {
513 struct testcase *t;
514 off_t len, rest, i;
515 const char **p;
516 char buf[BUFSIZ];
517 FILE *fp;
518
519 /* test fmemopen_seek(SEEK_CUR) */
520 for (t = &testcases[0]; t->s != NULL; ++t) {
521 len = (off_t)strnlen(t->s, t->n);
522 rest = (off_t)t->n - len;
523 for (p = &mode_a[0]; *p != NULL; ++p) {
524
525 memcpy(&buf[0], t->s, t->n);
526 fp = fmemopen(&buf[0], t->n, *p);
527 ATF_CHECK(fp != NULL);
528 /*
529 * test fmemopen_seek(SEEK_CUR)
530 */
531 #if defined(__GLIBC__)
532 if (i < (off_t)t->n) {
533 #endif
534 /* zero */
535 ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0);
536 ATF_CHECK(ftello(fp) == len);
537
538 /* posive */
539 for (i = (off_t)1; i <= rest; ++i) {
540 ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0);
541 ATF_CHECK(ftello(fp) == len + i);
542 }
543
544 /* positive + OOB */
545 ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1);
546 ATF_CHECK(ftello(fp) == (off_t)t->n);
547
548 /* negative */
549 for (i = (off_t)1; i <= (off_t)t->n; ++i) {
550 ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == 0);
551 ATF_CHECK(ftello(fp) == (off_t)t->n - i);
552 }
553
554 /* negative + OOB */
555 ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1);
556 ATF_CHECK(ftello(fp) == (off_t)0);
557
558 #if defined(__GLIBC__)
559 }
560 #endif
561 ATF_CHECK(fclose(fp) == 0);
562 }
563 }
564 }
565
566 ATF_TC(test12);
567 ATF_TC_HEAD(test12, tc)
568 {
569 atf_tc_set_md_var(tc, "descr", "test12");
570 }
571 ATF_TC_BODY(test12, tc)
572 {
573 struct testcase *t;
574 off_t len, rest, i;
575 const char **p;
576 char buf[BUFSIZ];
577 FILE *fp;
578
579 /* test fmemopen_seek(SEEK_END) */
580 for (t = &testcases[0]; t->s != NULL; ++t) {
581 len = (off_t)strnlen(t->s, t->n);
582 rest = t->n - len;
583 for (p = &mode_r[0]; *p != NULL; ++p) {
584
585 memcpy(buf, t->s, t->n);
586 fp = fmemopen(&buf[0], t->n, *p);
587 ATF_CHECK(fp != NULL);
588
589 /*
590 * test fmemopen_seek(SEEK_END)
591 */
592 #if !defined(__GLIBC__)
593 ATF_CHECK(ftello(fp) == (off_t)0);
594
595 /* zero */
596 ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
597 ATF_CHECK(ftello(fp) == len);
598
599 /* positive + OOB */
600 ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1);
601 ATF_CHECK(ftello(fp) == len);
602
603 /* negative + OOB */
604 ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1);
605 ATF_CHECK(ftello(fp) == len);
606
607 /* positive */
608 for (i = 1; i <= rest; ++i) {
609 ATF_CHECK(fseeko(fp, i, SEEK_END) == 0);
610 ATF_CHECK(ftello(fp) == len + i);
611 }
612
613 /* negative */
614 for (i = 1; i < len; ++i) {
615 ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0);
616 ATF_CHECK(ftello(fp) == len - i);
617 }
618 #endif
619 ATF_CHECK(fclose(fp) == 0);
620 }
621 }
622 }
623
624 ATF_TC(test13);
625 ATF_TC_HEAD(test13, tc)
626 {
627 atf_tc_set_md_var(tc, "descr", "test13");
628 }
629 ATF_TC_BODY(test13, tc)
630 {
631 struct testcase *t;
632 off_t len, rest, i;
633 const char **p;
634 char buf[BUFSIZ];
635 FILE *fp;
636
637 /* test fmemopen_seek(SEEK_END) */
638 for (t = &testcases[0]; t->s != NULL; ++t) {
639 len = (off_t)strnlen(t->s, t->n);
640 rest = t->n - len;
641 for (p = &mode_w[0]; *p != NULL; ++p) {
642
643 memcpy(buf, t->s, t->n);
644 fp = fmemopen(&buf[0], t->n, *p);
645 ATF_CHECK(fp != NULL);
646 /*
647 * test fmemopen_seek(SEEK_END)
648 */
649 #if !defined(__GLIBC__)
650 ATF_CHECK(ftello(fp) == (off_t)0);
651 ATF_CHECK(buf[0] == '\0');
652
653 /* zero */
654 ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
655 ATF_CHECK(ftello(fp) == (off_t)0);
656
657 /* positive + OOB */
658 ATF_CHECK(fseeko(fp, (off_t)t->n + 1, SEEK_END) == -1);
659 ATF_CHECK(ftello(fp) == (off_t)0);
660
661 /* negative + OOB */
662 ATF_CHECK(fseeko(fp, -1, SEEK_END) == -1);
663 ATF_CHECK(ftello(fp) == (off_t)0);
664
665 /* positive */
666 for (i = 1; i <= t->n; ++i) {
667 ATF_CHECK(fseeko(fp, i, SEEK_END) == 0);
668 ATF_CHECK(ftello(fp) == i);
669 }
670 #endif
671 ATF_CHECK(fclose(fp) == 0);
672 }
673 }
674 }
675
676 ATF_TC(test14);
677 ATF_TC_HEAD(test14, tc)
678 {
679 atf_tc_set_md_var(tc, "descr", "test14");
680 }
681 ATF_TC_BODY(test14, tc)
682 {
683 struct testcase *t;
684 off_t len, rest, i;
685 const char **p;
686 char buf[BUFSIZ];
687 FILE *fp;
688
689 /* test fmemopen_seek(SEEK_END) */
690 for (t = &testcases[0]; t->s != NULL; ++t) {
691 len = (off_t)strnlen(t->s, t->n);
692 rest = (off_t)t->n - len;
693 for (p = &mode_a[0]; *p != NULL; ++p) {
694
695 memcpy(buf, t->s, t->n);
696 fp = fmemopen(&buf[0], t->n, *p);
697 ATF_CHECK(fp != NULL);
698 /*
699 * test fmemopen_seek(SEEK_END)
700 */
701 #if !defined(__GLIBC__)
702 ATF_CHECK(ftello(fp) == len);
703
704 /* zero */
705 ATF_CHECK(fseeko(fp, 0, SEEK_END) == 0);
706 ATF_CHECK(ftello(fp) == len);
707
708 /* positive + OOB */
709 ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1);
710 ATF_CHECK(ftello(fp) == len);
711
712 /* negative + OOB */
713 ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1);
714 ATF_CHECK(ftello(fp) == len);
715
716 /* positive */
717 for (i = 1; i <= rest; ++i) {
718 ATF_CHECK(fseeko(fp, i, SEEK_END) == 0);
719 ATF_CHECK(ftello(fp) == len + i);
720 }
721
722 /* negative */
723 for (i = 1; i < len; ++i) {
724 ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0);
725 ATF_CHECK(ftello(fp) == len - i);
726 }
727 #endif
728 ATF_CHECK(fclose(fp) == 0);
729 }
730 }
731 }
732
733 const char *mode_rw1[] = {
734 "r", "rb", "r+", "rb+", "r+b",
735 "w+", "wb+",
736 NULL
737 };
738
739 /* test15 - 18:
740 * When a stream open for writing is flushed or closed, a null byte is written
741 * at the current position or at the end of the buffer, depending on the size
742 * of the contents.
743 */
744
745 ATF_TC(test15);
746 ATF_TC_HEAD(test15, tc)
747 {
748 atf_tc_set_md_var(tc, "descr", "test15");
749 }
750 ATF_TC_BODY(test15, tc)
751 {
752 struct testcase *t;
753 const char **p;
754 char buf0[BUFSIZ], buf1[BUFSIZ];
755 FILE *fp;
756 size_t i;
757
758 for (t = &testcases[0]; t->s != NULL; ++t) {
759 for (p = &mode_rw1[0]; *p != NULL; ++p) {
760
761 memcpy(&buf0[0], t->s, t->n);
762 fp = fmemopen(&buf0[0], t->n, *p);
763 ATF_CHECK(fp != NULL);
764 /*
765 * test fmemopen_read + fgetc(3)
766 */
767 for (i = (size_t)0; i < t->n; ++i) {
768 ATF_CHECK(ftello(fp) == (off_t)i);
769 ATF_CHECK(fgetc(fp) == buf0[i]);
770 ATF_CHECK(feof(fp) == 0);
771 ATF_CHECK(ftello(fp) == (off_t)i + 1);
772 }
773 ATF_CHECK(fgetc(fp) == EOF);
774 ATF_CHECK(feof(fp) != 0);
775 ATF_CHECK(ftello(fp) == (off_t)t->n);
776 ATF_CHECK(fclose(fp) == 0);
777 }
778 }
779 }
780
781 ATF_TC(test16);
782 ATF_TC_HEAD(test16, tc)
783 {
784 atf_tc_set_md_var(tc, "descr", "test16");
785 }
786 ATF_TC_BODY(test16, tc)
787 {
788 struct testcase *t;
789 const char **p;
790 char buf0[BUFSIZ], buf1[BUFSIZ];
791 FILE *fp;
792
793 for (t = &testcases[0]; t->s != NULL; ++t) {
794 for (p = &mode_rw1[0]; *p != NULL; ++p) {
795
796 memcpy(&buf0[0], t->s, t->n);
797 buf1[t->n] = 0x1;
798 fp = fmemopen(&buf0[0], t->n, *p);
799 ATF_CHECK(fp != NULL);
800 /*
801 * test fmemopen_read + fread(4)
802 */
803 ATF_CHECK(ftello(fp) == (off_t)0);
804 ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) == t->n);
805 ATF_CHECK(feof(fp) != 0);
806 ATF_CHECK(memcmp(&buf0[0], &buf1[0], t->n) == 0);
807 ATF_CHECK((unsigned char)buf1[t->n] == 0x1);
808
809 ATF_CHECK(fclose(fp) == 0);
810 }
811 }
812 }
813
814 const char *mode_a1[] = { "a+", "ab+", NULL };
815
816 ATF_TC(test17);
817 ATF_TC_HEAD(test17, tc)
818 {
819 atf_tc_set_md_var(tc, "descr", "test17");
820 }
821 ATF_TC_BODY(test17, tc)
822 {
823 struct testcase *t;
824 size_t len, i;
825 const char **p;
826 char buf[BUFSIZ];
827 FILE *fp;
828
829 for (t = &testcases[0]; t->s != NULL; ++t) {
830 len = strnlen(t->s, t->n);
831 for (p = &mode_a1[0]; *p != NULL; ++p) {
832
833 memcpy(&buf[0], t->s, t->n);
834 fp = fmemopen(&buf[0], t->n, *p);
835 ATF_CHECK(fp != NULL);
836 /*
837 * test fmemopen_read + fgetc(3)
838 */
839 #if defined(__GLIBC__)
840 if (i < t->n) {
841 #endif
842 for (i = len; i < t->n; ++i) {
843 ATF_CHECK(ftello(fp) == (off_t)i);
844 ATF_CHECK(fgetc(fp) == buf[i]);
845 ATF_CHECK(feof(fp) == 0);
846 ATF_CHECK(ftello(fp) == (off_t)i + 1);
847 }
848 ATF_CHECK(fgetc(fp) == EOF);
849 ATF_CHECK(feof(fp) != 0);
850 ATF_CHECK(ftello(fp) == (off_t)t->n);
851 rewind(fp);
852 for (i = (size_t)0; i < t->n; ++i) {
853 ATF_CHECK(ftello(fp) == (off_t)i);
854 ATF_CHECK(fgetc(fp) == buf[i]);
855 ATF_CHECK(feof(fp) == 0);
856 ATF_CHECK(ftello(fp) == (off_t)i + 1);
857 }
858 ATF_CHECK(fgetc(fp) == EOF);
859 ATF_CHECK(feof(fp) != 0);
860 ATF_CHECK(ftello(fp) == (off_t)t->n);
861 #if defined(__GLIBC__)
862 }
863 #endif
864 ATF_CHECK(fclose(fp) == 0);
865 }
866 }
867 }
868
869 ATF_TC(test18);
870 ATF_TC_HEAD(test18, tc)
871 {
872 atf_tc_set_md_var(tc, "descr", "test18");
873 }
874 ATF_TC_BODY(test18, tc)
875 {
876 struct testcase *t;
877 size_t len, i;
878 const char **p;
879 char buf0[BUFSIZ], buf1[BUFSIZ];
880 FILE *fp;
881
882 for (t = &testcases[0]; t->s != NULL; ++t) {
883 len = strnlen(t->s, t->n);
884 for (p = &mode_a1[0]; *p != NULL; ++p) {
885
886 memcpy(&buf0[0], t->s, t->n);
887 buf1[t->n - len] = 0x1;
888 fp = fmemopen(&buf0[0], t->n, *p);
889 ATF_CHECK(fp != NULL);
890 /*
891 * test fmemopen_read + fread(3)
892 */
893 #if defined(__GLIBC__)
894 if (i < t->n) {
895 #endif
896 ATF_CHECK(ftello(fp) == (off_t)len);
897 ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp)
898 == t->n - len);
899 ATF_CHECK(feof(fp) != 0);
900 ATF_CHECK(!memcmp(&buf0[len], &buf1[0], t->n - len));
901 ATF_CHECK((unsigned char)buf1[t->n - len] == 0x1);
902 rewind(fp);
903 buf1[t->n] = 0x1;
904 ATF_CHECK(ftello(fp) == (off_t)0);
905 ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp)
906 == t->n);
907 ATF_CHECK(feof(fp) != 0);
908 ATF_CHECK(!memcmp(&buf0[0], &buf1[0], t->n));
909 ATF_CHECK((unsigned char)buf1[t->n] == 0x1);
910 #if defined(__GLIBC__)
911 }
912 #endif
913 ATF_CHECK(fclose(fp) == 0);
914 }
915 }
916 }
917
918 /*
919 * test19 - test22:
920 * If a stream open for update is flushed or closed and the last write has
921 * advanced the current buffer size, a null byte is written at the end of the
922 * buffer if it fits.
923 */
924
925 const char *mode_rw2[] = {
926 "r+", "rb+", "r+b",
927 "w", "wb", "w+", "wb+", "w+b",
928 NULL
929 };
930
931 ATF_TC(test19);
932 ATF_TC_HEAD(test19, tc)
933 {
934 atf_tc_set_md_var(tc, "descr", "test19");
935 }
936 ATF_TC_BODY(test19, tc)
937 {
938 struct testcase *t;
939 size_t len, i;
940 const char **p;
941 char buf[BUFSIZ];
942 FILE *fp;
943
944 for (t = &testcases[0]; t->s != NULL; ++t) {
945 len = strnlen(t->s, t->n);
946 for (p = &mode_rw2[0]; *p != NULL; ++p) {
947
948 memcpy(&buf[0], t->s, t->n);
949 buf[t->n] = 0x1;
950 fp = fmemopen(&buf[0], t->n + 1, *p);
951 ATF_CHECK(fp != NULL);
952 setbuf(fp, NULL);
953 /*
954 * test fmemopen_write + fputc(3)
955 */
956 for (i = (size_t)0; i < t->n; ++i) {
957 ATF_CHECK(ftello(fp) == (off_t)i);
958 ATF_CHECK(fputc(t->s[i], fp) == t->s[i]);
959 ATF_CHECK(buf[i] == t->s[i]);
960 ATF_CHECK(ftello(fp) == (off_t)i + 1);
961 ATF_CHECK(buf[i] == t->s[i]);
962 #if !defined(__GLIBC__)
963 ATF_CHECK(buf[i + 1] == '\0');
964 #endif
965 }
966
967 /* don't accept non nul character at end of buffer */
968 ATF_CHECK(fputc(0x1, fp) == EOF);
969 ATF_CHECK(ftello(fp) == (off_t)t->n);
970 ATF_CHECK(feof(fp) == 0);
971
972 /* accept nul character at end of buffer */
973 ATF_CHECK(fputc('\0', fp) == '\0');
974 ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
975 ATF_CHECK(feof(fp) == 0);
976
977 /* reach EOF */
978 ATF_CHECK(fputc('\0', fp) == EOF);
979 ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
980
981 /* compare */
982 ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0);
983 ATF_CHECK(buf[t->n] == '\0');
984
985 ATF_CHECK(fclose(fp) == 0);
986 }
987 }
988 }
989
990 ATF_TC(test20);
991 ATF_TC_HEAD(test20, tc)
992 {
993 atf_tc_set_md_var(tc, "descr", "test20");
994 }
995 ATF_TC_BODY(test20, tc)
996 {
997 struct testcase *t;
998 size_t len, i;
999 const char **p;
1000 char buf[BUFSIZ];
1001 FILE *fp;
1002
1003 for (t = &testcases[0]; t->s != NULL; ++t) {
1004 len = strnlen(t->s, t->n);
1005 for (p = &mode_rw2[0]; *p != NULL; ++p) {
1006
1007 memcpy(&buf[0], t->s, t->n);
1008 buf[t->n] = 0x1;
1009 fp = fmemopen(&buf[0], t->n + 1, *p);
1010 ATF_CHECK(fp != NULL);
1011 setbuf(fp, NULL);
1012 ATF_CHECK(fwrite(t->s, 1, t->n, fp) == t->n);
1013 /*
1014 * test fmemopen_write + fwrite(3)
1015 */
1016 #if !defined(__GLIBC__)
1017 ATF_CHECK(buf[t->n] == '\0');
1018
1019 /* don't accept non nul character at end of buffer */
1020 ATF_CHECK(fwrite("\x1", 1, 1, fp) == 0);
1021 ATF_CHECK(ftello(fp) == (off_t)t->n);
1022 ATF_CHECK(feof(fp) == 0);
1023 #endif
1024
1025 /* accept nul character at end of buffer */
1026 ATF_CHECK(fwrite("\x0", 1, 1, fp) == 1);
1027 ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
1028 ATF_CHECK(feof(fp) == 0);
1029
1030 /* reach EOF */
1031 ATF_CHECK(fputc('\0', fp) == EOF);
1032 ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
1033
1034 /* compare */
1035 ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0);
1036 ATF_CHECK(buf[t->n] == '\0');
1037
1038 ATF_CHECK(fclose(fp) == 0);
1039 }
1040 }
1041 }
1042
1043 ATF_TC(test21);
1044 ATF_TC_HEAD(test21, tc)
1045 {
1046 atf_tc_set_md_var(tc, "descr", "test21");
1047 }
1048 ATF_TC_BODY(test21, tc)
1049 {
1050 struct testcase *t;
1051 size_t len, i;
1052 const char **p;
1053 char buf[BUFSIZ];
1054 FILE *fp;
1055
1056 for (t = &testcases[0]; t->s != NULL; ++t) {
1057 len = strnlen(t->s, t->n);
1058 for (p = &mode_a[0]; *p != NULL; ++p) {
1059 memcpy(&buf[0], t->s, t->n);
1060 fp = fmemopen(&buf[0], t->n, *p);
1061 ATF_CHECK(fp != NULL);
1062 setbuf(fp, NULL);
1063 /*
1064 * test fmemopen_write + fputc(3)
1065 */
1066 if (len < t->n) {
1067 for (i = len; i < t->n - 1; ++i) {
1068 ATF_CHECK(ftello(fp) == (off_t)i);
1069 ATF_CHECK(fputc(t->s[i - len], fp)
1070 == t->s[i - len]);
1071 ATF_CHECK(buf[i] == t->s[i - len]);
1072 ATF_CHECK(ftello(fp) == (off_t)i + 1);
1073 #if !defined(__GLIBC__)
1074 ATF_CHECK(buf[i + 1] == '\0');
1075 #endif
1076 }
1077
1078 /* don't accept non nul character at end of buffer */
1079 ATF_CHECK(ftello(fp) == (off_t)t->n - 1);
1080 ATF_CHECK(fputc(0x1, fp) == EOF);
1081 ATF_CHECK(ftello(fp) == (off_t)t->n - 1);
1082
1083 /* accept nul character at end of buffer */
1084 ATF_CHECK(ftello(fp) == (off_t)t->n - 1);
1085 ATF_CHECK(fputc('\0', fp) == '\0');
1086 ATF_CHECK(ftello(fp) == (off_t)t->n);
1087 }
1088
1089 /* reach EOF */
1090 ATF_CHECK(ftello(fp) == (off_t)t->n);
1091 ATF_CHECK(fputc('\0', fp) == EOF);
1092 ATF_CHECK(ftello(fp) == (off_t)t->n);
1093
1094 ATF_CHECK(fclose(fp) == 0);
1095 }
1096 }
1097 }
1098
1099 ATF_TC(test22);
1100 ATF_TC_HEAD(test22, tc)
1101 {
1102 atf_tc_set_md_var(tc, "descr", "test22");
1103 }
1104 ATF_TC_BODY(test22, tc)
1105 {
1106 struct testcase *t0, *t1;
1107 size_t len0, len1, i, nleft;
1108 const char **p;
1109 char buf[BUFSIZ];
1110 FILE *fp;
1111
1112 for (t0 = &testcases[0]; t0->s != NULL; ++t0) {
1113 len0 = strnlen(t0->s, t0->n);
1114 for (t1 = &testcases[0]; t1->s != NULL; ++t1) {
1115 len1 = strnlen(t1->s, t1->n);
1116 for (p = &mode_a[0]; *p != NULL; ++p) {
1117
1118 memcpy(&buf[0], t0->s, t0->n);
1119 fp = fmemopen(&buf[0], t0->n, *p);
1120 ATF_CHECK(fp != NULL);
1121 setbuf(fp, NULL);
1122 /*
1123 * test fmemopen_write + fwrite(3)
1124 */
1125 nleft = t0->n - len0;
1126 #if !defined(__GLIBC__)
1127 if (nleft == 0 || len1 == nleft - 1) {
1128 ATF_CHECK(fwrite(t1->s, 1, t1->n, fp)
1129 == nleft);
1130 ATF_CHECK(ftell(fp) == t1->n);
1131 } else {
1132 ATF_CHECK(fwrite(t1->s, 1, t1->n, fp)
1133 == nleft - 1);
1134 ATF_CHECK(ftell(fp) == t1->n - 1);
1135 }
1136 #endif
1137 ATF_CHECK(fclose(fp) == 0);
1138 }
1139 }
1140 }
1141 }
1142
1143 ATF_TP_ADD_TCS(tp)
1144 {
1145 ATF_TP_ADD_TC(tp, test00);
1146 ATF_TP_ADD_TC(tp, test01);
1147 ATF_TP_ADD_TC(tp, test02);
1148 ATF_TP_ADD_TC(tp, test03);
1149 ATF_TP_ADD_TC(tp, test04);
1150 ATF_TP_ADD_TC(tp, test05);
1151 ATF_TP_ADD_TC(tp, test06);
1152 ATF_TP_ADD_TC(tp, test07);
1153 ATF_TP_ADD_TC(tp, test08);
1154 ATF_TP_ADD_TC(tp, test09);
1155 ATF_TP_ADD_TC(tp, test10);
1156 ATF_TP_ADD_TC(tp, test11);
1157 ATF_TP_ADD_TC(tp, test12);
1158 ATF_TP_ADD_TC(tp, test13);
1159 ATF_TP_ADD_TC(tp, test14);
1160 ATF_TP_ADD_TC(tp, test15);
1161 ATF_TP_ADD_TC(tp, test16);
1162 ATF_TP_ADD_TC(tp, test17);
1163 ATF_TP_ADD_TC(tp, test18);
1164 ATF_TP_ADD_TC(tp, test19);
1165 ATF_TP_ADD_TC(tp, test20);
1166 ATF_TP_ADD_TC(tp, test21);
1167 ATF_TP_ADD_TC(tp, test22);
1168
1169 return atf_no_error();
1170 }
1171