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