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