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