t_fmemopen.c revision 272345
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(__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 59const 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 66const char *mode_r[] = { "r", "rb", "r+", "rb+", "r+b", NULL }; 67const char *mode_w[] = { "w", "wb", "w+", "wb+", "w+b", NULL }; 68const char *mode_a[] = { "a", "ab", "a+", "ab+", "a+b", NULL }; 69 70struct 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 122ATF_TC(test00); 123ATF_TC_HEAD(test00, tc) 124{ 125 atf_tc_set_md_var(tc, "descr", "test00"); 126} 127ATF_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 145ATF_TC(test01); 146ATF_TC_HEAD(test01, tc) 147{ 148 atf_tc_set_md_var(tc, "descr", "test01"); 149} 150ATF_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 179ATF_TC(test02); 180ATF_TC_HEAD(test02, tc) 181{ 182 atf_tc_set_md_var(tc, "descr", "test02"); 183} 184ATF_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 215ATF_TC(test03); 216ATF_TC_HEAD(test03, tc) 217{ 218 atf_tc_set_md_var(tc, "descr", "test03"); 219} 220ATF_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 249ATF_TC(test04); 250ATF_TC_HEAD(test04, tc) 251{ 252 atf_tc_set_md_var(tc, "descr", "test04"); 253} 254ATF_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 292ATF_TC(test05); 293ATF_TC_HEAD(test05, tc) 294{ 295 atf_tc_set_md_var(tc, "descr", "test05"); 296} 297ATF_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 320ATF_TC(test06); 321ATF_TC_HEAD(test06, tc) 322{ 323 atf_tc_set_md_var(tc, "descr", "test06"); 324} 325ATF_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 341ATF_TC(test07); 342ATF_TC_HEAD(test07, tc) 343{ 344 atf_tc_set_md_var(tc, "descr", "test07"); 345} 346ATF_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 372ATF_TC(test08); 373ATF_TC_HEAD(test08, tc) 374{ 375 atf_tc_set_md_var(tc, "descr", "test08"); 376} 377ATF_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 407ATF_TC(test09); 408ATF_TC_HEAD(test09, tc) 409{ 410 atf_tc_set_md_var(tc, "descr", "test09"); 411} 412ATF_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 452const char *mode_rw[] = { 453 "r", "rb", "r+", "rb+", "r+b", 454 "w", "wb", "w+", "wb+", "w+b", 455 NULL 456}; 457 458ATF_TC(test10); 459ATF_TC_HEAD(test10, tc) 460{ 461 atf_tc_set_md_var(tc, "descr", "test10"); 462} 463ATF_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 506ATF_TC(test11); 507ATF_TC_HEAD(test11, tc) 508{ 509 atf_tc_set_md_var(tc, "descr", "test11"); 510} 511ATF_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 566ATF_TC(test12); 567ATF_TC_HEAD(test12, tc) 568{ 569 atf_tc_set_md_var(tc, "descr", "test12"); 570} 571ATF_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 624ATF_TC(test13); 625ATF_TC_HEAD(test13, tc) 626{ 627 atf_tc_set_md_var(tc, "descr", "test13"); 628} 629ATF_TC_BODY(test13, tc) 630{ 631 struct testcase *t; 632 off_t 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 for (p = &mode_w[0]; *p != NULL; ++p) { 640 641 memcpy(buf, t->s, t->n); 642 fp = fmemopen(&buf[0], t->n, *p); 643 ATF_CHECK(fp != NULL); 644/* 645 * test fmemopen_seek(SEEK_END) 646 */ 647#if !defined(__GLIBC__) 648 ATF_CHECK(ftello(fp) == (off_t)0); 649 ATF_CHECK(buf[0] == '\0'); 650 651 /* zero */ 652 ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); 653 ATF_CHECK(ftello(fp) == (off_t)0); 654 655 /* positive + OOB */ 656 ATF_CHECK(fseeko(fp, (off_t)t->n + 1, SEEK_END) == -1); 657 ATF_CHECK(ftello(fp) == (off_t)0); 658 659 /* negative + OOB */ 660 ATF_CHECK(fseeko(fp, -1, SEEK_END) == -1); 661 ATF_CHECK(ftello(fp) == (off_t)0); 662 663 /* positive */ 664 for (i = 1; i <= t->n; ++i) { 665 ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); 666 ATF_CHECK(ftello(fp) == i); 667 } 668#endif 669 ATF_CHECK(fclose(fp) == 0); 670 } 671 } 672} 673 674ATF_TC(test14); 675ATF_TC_HEAD(test14, tc) 676{ 677 atf_tc_set_md_var(tc, "descr", "test14"); 678} 679ATF_TC_BODY(test14, tc) 680{ 681 struct testcase *t; 682 off_t len, rest, i; 683 const char **p; 684 char buf[BUFSIZ]; 685 FILE *fp; 686 687 /* test fmemopen_seek(SEEK_END) */ 688 for (t = &testcases[0]; t->s != NULL; ++t) { 689 len = (off_t)strnlen(t->s, t->n); 690 rest = (off_t)t->n - len; 691 for (p = &mode_a[0]; *p != NULL; ++p) { 692 693 memcpy(buf, t->s, t->n); 694 fp = fmemopen(&buf[0], t->n, *p); 695 ATF_CHECK(fp != NULL); 696/* 697 * test fmemopen_seek(SEEK_END) 698 */ 699#if !defined(__GLIBC__) 700 ATF_CHECK(ftello(fp) == len); 701 702 /* zero */ 703 ATF_CHECK(fseeko(fp, 0, SEEK_END) == 0); 704 ATF_CHECK(ftello(fp) == len); 705 706 /* positive + OOB */ 707 ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1); 708 ATF_CHECK(ftello(fp) == len); 709 710 /* negative + OOB */ 711 ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1); 712 ATF_CHECK(ftello(fp) == len); 713 714 /* positive */ 715 for (i = 1; i <= rest; ++i) { 716 ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); 717 ATF_CHECK(ftello(fp) == len + i); 718 } 719 720 /* negative */ 721 for (i = 1; i < len; ++i) { 722 ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0); 723 ATF_CHECK(ftello(fp) == len - i); 724 } 725#endif 726 ATF_CHECK(fclose(fp) == 0); 727 } 728 } 729} 730 731const char *mode_rw1[] = { 732 "r", "rb", "r+", "rb+", "r+b", 733 "w+", "wb+", 734 NULL 735}; 736 737/* test15 - 18: 738 * When a stream open for writing is flushed or closed, a null byte is written 739 * at the current position or at the end of the buffer, depending on the size 740 * of the contents. 741 */ 742 743ATF_TC(test15); 744ATF_TC_HEAD(test15, tc) 745{ 746 atf_tc_set_md_var(tc, "descr", "test15"); 747} 748ATF_TC_BODY(test15, tc) 749{ 750 struct testcase *t; 751 const char **p; 752 char buf0[BUFSIZ]; 753 FILE *fp; 754 int i; 755 756 for (t = &testcases[0]; t->s != NULL; ++t) { 757 for (p = &mode_rw1[0]; *p != NULL; ++p) { 758 759 memcpy(&buf0[0], t->s, t->n); 760 fp = fmemopen(&buf0[0], t->n, *p); 761 ATF_CHECK(fp != NULL); 762/* 763 * test fmemopen_read + fgetc(3) 764 */ 765 for (i = 0; i < t->n; ++i) { 766 ATF_CHECK(ftello(fp) == (off_t)i); 767 ATF_CHECK(fgetc(fp) == buf0[i]); 768 ATF_CHECK(feof(fp) == 0); 769 ATF_CHECK(ftello(fp) == (off_t)i + 1); 770 } 771 ATF_CHECK(fgetc(fp) == EOF); 772 ATF_CHECK(feof(fp) != 0); 773 ATF_CHECK(ftello(fp) == (off_t)t->n); 774 ATF_CHECK(fclose(fp) == 0); 775 } 776 } 777} 778 779ATF_TC(test16); 780ATF_TC_HEAD(test16, tc) 781{ 782 atf_tc_set_md_var(tc, "descr", "test16"); 783} 784ATF_TC_BODY(test16, tc) 785{ 786 struct testcase *t; 787 const char **p; 788 char buf0[BUFSIZ], buf1[BUFSIZ]; 789 FILE *fp; 790 791 for (t = &testcases[0]; t->s != NULL; ++t) { 792 for (p = &mode_rw1[0]; *p != NULL; ++p) { 793 794 memcpy(&buf0[0], t->s, t->n); 795 buf1[t->n] = 0x1; 796 fp = fmemopen(&buf0[0], t->n, *p); 797 ATF_CHECK(fp != NULL); 798/* 799 * test fmemopen_read + fread(4) 800 */ 801 ATF_CHECK(ftello(fp) == (off_t)0); 802 ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) == (size_t)t->n); 803 ATF_CHECK(feof(fp) != 0); 804 ATF_CHECK(memcmp(&buf0[0], &buf1[0], t->n) == 0); 805 ATF_CHECK((unsigned char)buf1[t->n] == 0x1); 806 807 ATF_CHECK(fclose(fp) == 0); 808 } 809 } 810} 811 812const char *mode_a1[] = { "a+", "ab+", NULL }; 813 814ATF_TC(test17); 815ATF_TC_HEAD(test17, tc) 816{ 817 atf_tc_set_md_var(tc, "descr", "test17"); 818} 819ATF_TC_BODY(test17, tc) 820{ 821 struct testcase *t; 822 size_t len; 823 int i; 824 const char **p; 825 char buf[BUFSIZ]; 826 FILE *fp; 827 828 for (t = &testcases[0]; t->s != NULL; ++t) { 829 len = strnlen(t->s, t->n); 830 for (p = &mode_a1[0]; *p != NULL; ++p) { 831 832 memcpy(&buf[0], t->s, t->n); 833 fp = fmemopen(&buf[0], t->n, *p); 834 ATF_CHECK(fp != NULL); 835/* 836 * test fmemopen_read + fgetc(3) 837 */ 838#if defined(__GLIBC__) 839 if (i < t->n) { 840#endif 841 for (i = len; i < t->n; ++i) { 842 ATF_CHECK(ftello(fp) == (off_t)i); 843 ATF_CHECK(fgetc(fp) == buf[i]); 844 ATF_CHECK(feof(fp) == 0); 845 ATF_CHECK(ftello(fp) == (off_t)i + 1); 846 } 847 ATF_CHECK(fgetc(fp) == EOF); 848 ATF_CHECK(feof(fp) != 0); 849 ATF_CHECK(ftello(fp) == (off_t)t->n); 850 rewind(fp); 851 for (i = 0; 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#if defined(__GLIBC__) 861 } 862#endif 863 ATF_CHECK(fclose(fp) == 0); 864 } 865 } 866} 867 868ATF_TC(test18); 869ATF_TC_HEAD(test18, tc) 870{ 871 atf_tc_set_md_var(tc, "descr", "test18"); 872} 873ATF_TC_BODY(test18, tc) 874{ 875 struct testcase *t; 876 size_t len; 877 const char **p; 878 char buf0[BUFSIZ], buf1[BUFSIZ]; 879 FILE *fp; 880 881 for (t = &testcases[0]; t->s != NULL; ++t) { 882 len = strnlen(t->s, t->n); 883 for (p = &mode_a1[0]; *p != NULL; ++p) { 884 885 memcpy(&buf0[0], t->s, t->n); 886 buf1[t->n - len] = 0x1; 887 fp = fmemopen(&buf0[0], t->n, *p); 888 ATF_CHECK(fp != NULL); 889/* 890 * test fmemopen_read + fread(3) 891 */ 892#if defined(__GLIBC__) 893 if (i < t->n) { 894#endif 895 ATF_CHECK(ftello(fp) == (off_t)len); 896 ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) 897 == t->n - len); 898 ATF_CHECK(feof(fp) != 0); 899 ATF_CHECK(!memcmp(&buf0[len], &buf1[0], t->n - len)); 900 ATF_CHECK((unsigned char)buf1[t->n - len] == 0x1); 901 rewind(fp); 902 buf1[t->n] = 0x1; 903 ATF_CHECK(ftello(fp) == (off_t)0); 904 ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) 905 == (size_t)t->n); 906 ATF_CHECK(feof(fp) != 0); 907 ATF_CHECK(!memcmp(&buf0[0], &buf1[0], t->n)); 908 ATF_CHECK((unsigned char)buf1[t->n] == 0x1); 909#if defined(__GLIBC__) 910 } 911#endif 912 ATF_CHECK(fclose(fp) == 0); 913 } 914 } 915} 916 917/* 918 * test19 - test22: 919 * If a stream open for update is flushed or closed and the last write has 920 * advanced the current buffer size, a null byte is written at the end of the 921 * buffer if it fits. 922 */ 923 924const char *mode_rw2[] = { 925 "r+", "rb+", "r+b", 926 "w", "wb", "w+", "wb+", "w+b", 927 NULL 928}; 929 930ATF_TC(test19); 931ATF_TC_HEAD(test19, tc) 932{ 933 atf_tc_set_md_var(tc, "descr", "test19"); 934} 935ATF_TC_BODY(test19, tc) 936{ 937 struct testcase *t; 938 int i; 939 const char **p; 940 char buf[BUFSIZ]; 941 FILE *fp; 942 943 for (t = &testcases[0]; t->s != NULL; ++t) { 944 for (p = &mode_rw2[0]; *p != NULL; ++p) { 945 946 memcpy(&buf[0], t->s, t->n); 947 buf[t->n] = 0x1; 948 fp = fmemopen(&buf[0], t->n + 1, *p); 949 ATF_CHECK(fp != NULL); 950 setbuf(fp, NULL); 951/* 952 * test fmemopen_write + fputc(3) 953 */ 954 for (i = 0; i < t->n; ++i) { 955 ATF_CHECK(ftello(fp) == (off_t)i); 956 ATF_CHECK(fputc(t->s[i], fp) == t->s[i]); 957 ATF_CHECK(buf[i] == t->s[i]); 958 ATF_CHECK(ftello(fp) == (off_t)i + 1); 959 ATF_CHECK(buf[i] == t->s[i]); 960#if !defined(__GLIBC__) 961 ATF_CHECK(buf[i + 1] == '\0'); 962#endif 963 } 964 965/* don't accept non nul character at end of buffer */ 966 ATF_CHECK(fputc(0x1, fp) == EOF); 967 ATF_CHECK(ftello(fp) == (off_t)t->n); 968 ATF_CHECK(feof(fp) == 0); 969 970/* accept nul character at end of buffer */ 971 ATF_CHECK(fputc('\0', fp) == '\0'); 972 ATF_CHECK(ftello(fp) == (off_t)t->n + 1); 973 ATF_CHECK(feof(fp) == 0); 974 975/* reach EOF */ 976 ATF_CHECK(fputc('\0', fp) == EOF); 977 ATF_CHECK(ftello(fp) == (off_t)t->n + 1); 978 979 /* compare */ 980 ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0); 981 ATF_CHECK(buf[t->n] == '\0'); 982 983 ATF_CHECK(fclose(fp) == 0); 984 } 985 } 986} 987 988ATF_TC(test20); 989ATF_TC_HEAD(test20, tc) 990{ 991 atf_tc_set_md_var(tc, "descr", "test20"); 992} 993ATF_TC_BODY(test20, tc) 994{ 995 struct testcase *t; 996 const char **p; 997 char buf[BUFSIZ]; 998 FILE *fp; 999 1000 for (t = &testcases[0]; t->s != NULL; ++t) { 1001 for (p = &mode_rw2[0]; *p != NULL; ++p) { 1002 1003 memcpy(&buf[0], t->s, t->n); 1004 buf[t->n] = 0x1; 1005 fp = fmemopen(&buf[0], t->n + 1, *p); 1006 ATF_CHECK(fp != NULL); 1007 setbuf(fp, NULL); 1008 ATF_CHECK(fwrite(t->s, 1, t->n, fp) == (size_t)t->n); 1009/* 1010 * test fmemopen_write + fwrite(3) 1011 */ 1012#if !defined(__GLIBC__) 1013 ATF_CHECK(buf[t->n] == '\0'); 1014 1015/* don't accept non nul character at end of buffer */ 1016 ATF_CHECK(fwrite("\x1", 1, 1, fp) == 0); 1017 ATF_CHECK(ftello(fp) == (off_t)t->n); 1018 ATF_CHECK(feof(fp) == 0); 1019#endif 1020 1021/* accept nul character at end of buffer */ 1022 ATF_CHECK(fwrite("\x0", 1, 1, fp) == 1); 1023 ATF_CHECK(ftello(fp) == (off_t)t->n + 1); 1024 ATF_CHECK(feof(fp) == 0); 1025 1026/* reach EOF */ 1027 ATF_CHECK(fputc('\0', fp) == EOF); 1028 ATF_CHECK(ftello(fp) == (off_t)t->n + 1); 1029 1030/* compare */ 1031 ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0); 1032 ATF_CHECK(buf[t->n] == '\0'); 1033 1034 ATF_CHECK(fclose(fp) == 0); 1035 } 1036 } 1037} 1038 1039ATF_TC(test21); 1040ATF_TC_HEAD(test21, tc) 1041{ 1042 atf_tc_set_md_var(tc, "descr", "test21"); 1043} 1044ATF_TC_BODY(test21, tc) 1045{ 1046 struct testcase *t; 1047 int len, i; 1048 const char **p; 1049 char buf[BUFSIZ]; 1050 FILE *fp; 1051 1052 for (t = &testcases[0]; t->s != NULL; ++t) { 1053 len = strnlen(t->s, t->n); 1054 for (p = &mode_a[0]; *p != NULL; ++p) { 1055 memcpy(&buf[0], t->s, t->n); 1056 fp = fmemopen(&buf[0], t->n, *p); 1057 ATF_CHECK(fp != NULL); 1058 setbuf(fp, NULL); 1059/* 1060 * test fmemopen_write + fputc(3) 1061 */ 1062 if (len < t->n) { 1063 for (i = len; i < t->n - 1; ++i) { 1064 ATF_CHECK(ftello(fp) == (off_t)i); 1065 ATF_CHECK(fputc(t->s[i - len], fp) 1066 == t->s[i - len]); 1067 ATF_CHECK(buf[i] == t->s[i - len]); 1068 ATF_CHECK(ftello(fp) == (off_t)i + 1); 1069#if !defined(__GLIBC__) 1070 ATF_CHECK(buf[i + 1] == '\0'); 1071#endif 1072 } 1073 1074/* don't accept non nul character at end of buffer */ 1075 ATF_CHECK(ftello(fp) == (off_t)t->n - 1); 1076 ATF_CHECK(fputc(0x1, fp) == EOF); 1077 ATF_CHECK(ftello(fp) == (off_t)t->n - 1); 1078 1079/* accept nul character at end of buffer */ 1080 ATF_CHECK(ftello(fp) == (off_t)t->n - 1); 1081 ATF_CHECK(fputc('\0', fp) == '\0'); 1082 ATF_CHECK(ftello(fp) == (off_t)t->n); 1083 } 1084 1085/* reach EOF */ 1086 ATF_CHECK(ftello(fp) == (off_t)t->n); 1087 ATF_CHECK(fputc('\0', fp) == EOF); 1088 ATF_CHECK(ftello(fp) == (off_t)t->n); 1089 1090 ATF_CHECK(fclose(fp) == 0); 1091 } 1092 } 1093} 1094 1095ATF_TC(test22); 1096ATF_TC_HEAD(test22, tc) 1097{ 1098 atf_tc_set_md_var(tc, "descr", "test22"); 1099} 1100ATF_TC_BODY(test22, tc) 1101{ 1102 struct testcase *t0, *t1; 1103 size_t len0, len1, nleft; 1104 const char **p; 1105 char buf[BUFSIZ]; 1106 FILE *fp; 1107 1108 for (t0 = &testcases[0]; t0->s != NULL; ++t0) { 1109 len0 = strnlen(t0->s, t0->n); 1110 for (t1 = &testcases[0]; t1->s != NULL; ++t1) { 1111 len1 = strnlen(t1->s, t1->n); 1112 for (p = &mode_a[0]; *p != NULL; ++p) { 1113 1114 memcpy(&buf[0], t0->s, t0->n); 1115 fp = fmemopen(&buf[0], t0->n, *p); 1116 ATF_CHECK(fp != NULL); 1117 setbuf(fp, NULL); 1118/* 1119 * test fmemopen_write + fwrite(3) 1120 */ 1121 nleft = t0->n - len0; 1122#if !defined(__GLIBC__) 1123 if (nleft == 0 || len1 == nleft - 1) { 1124 ATF_CHECK(fwrite(t1->s, 1, t1->n, fp) 1125 == nleft); 1126 ATF_CHECK(ftell(fp) == t1->n); 1127 } else { 1128 ATF_CHECK(fwrite(t1->s, 1, t1->n, fp) 1129 == nleft - 1); 1130 ATF_CHECK(ftell(fp) == t1->n - 1); 1131 } 1132#endif 1133 ATF_CHECK(fclose(fp) == 0); 1134 } 1135 } 1136 } 1137} 1138 1139ATF_TP_ADD_TCS(tp) 1140{ 1141 ATF_TP_ADD_TC(tp, test00); 1142 ATF_TP_ADD_TC(tp, test01); 1143 ATF_TP_ADD_TC(tp, test02); 1144 ATF_TP_ADD_TC(tp, test03); 1145 ATF_TP_ADD_TC(tp, test04); 1146 ATF_TP_ADD_TC(tp, test05); 1147 ATF_TP_ADD_TC(tp, test06); 1148 ATF_TP_ADD_TC(tp, test07); 1149 ATF_TP_ADD_TC(tp, test08); 1150 ATF_TP_ADD_TC(tp, test09); 1151 ATF_TP_ADD_TC(tp, test10); 1152 ATF_TP_ADD_TC(tp, test11); 1153 ATF_TP_ADD_TC(tp, test12); 1154 ATF_TP_ADD_TC(tp, test13); 1155 ATF_TP_ADD_TC(tp, test14); 1156 ATF_TP_ADD_TC(tp, test15); 1157 ATF_TP_ADD_TC(tp, test16); 1158 ATF_TP_ADD_TC(tp, test17); 1159 ATF_TP_ADD_TC(tp, test18); 1160 ATF_TP_ADD_TC(tp, test19); 1161 ATF_TP_ADD_TC(tp, test20); 1162 ATF_TP_ADD_TC(tp, test21); 1163 ATF_TP_ADD_TC(tp, test22); 1164 1165 return atf_no_error(); 1166} 1167