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 } 1182