1 /* $NetBSD: t_fmemopen.c,v 1.3 2011/08/22 00:33:16 dholland 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 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 len, i; 467 const char **p; 468 char buf[BUFSIZ]; 469 FILE *fp; 470 471 for (t = &testcases[0]; t->s != NULL; ++t) { 472 len = (off_t)strnlen(t->s, t->n); 473 for (p = &mode_rw[0]; *p != NULL; ++p) { 474 475 memcpy(&buf[0], t->s, t->n); 476 fp = fmemopen(&buf[0], t->n, *p); 477 ATF_CHECK(fp != NULL); 478 479 /* 480 * test fmemopen_seek(SEEK_CUR) 481 */ 482 ATF_CHECK(ftello(fp) == (off_t)0); 483 484 /* zero */ 485 ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0); 486 ATF_CHECK(ftello(fp) == (off_t)0); 487 488 /* negative & OOB */ 489 ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1); 490 ATF_CHECK(ftello(fp) == (off_t)0); 491 492 /* positive */ 493 for (i = 0; i < (off_t)t->n; ++i) { 494 ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0); 495 ATF_CHECK(ftello(fp) == i + 1); 496 } 497 498 /* positive & OOB */ 499 ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1); 500 ATF_CHECK(ftello(fp) == (off_t)t->n); 501 502 ATF_CHECK(fclose(fp) == 0); 503 } 504 } 505 } 506 507 ATF_TC(test11); 508 ATF_TC_HEAD(test11, tc) 509 { 510 atf_tc_set_md_var(tc, "descr", "test11"); 511 } 512 ATF_TC_BODY(test11, tc) 513 { 514 struct testcase *t; 515 off_t len, rest, i; 516 const char **p; 517 char buf[BUFSIZ]; 518 FILE *fp; 519 520 /* test fmemopen_seek(SEEK_CUR) */ 521 for (t = &testcases[0]; t->s != NULL; ++t) { 522 len = (off_t)strnlen(t->s, t->n); 523 rest = (off_t)t->n - len; 524 for (p = &mode_a[0]; *p != NULL; ++p) { 525 526 memcpy(&buf[0], t->s, t->n); 527 fp = fmemopen(&buf[0], t->n, *p); 528 ATF_CHECK(fp != NULL); 529 /* 530 * test fmemopen_seek(SEEK_CUR) 531 */ 532 #if defined(__GLIBC__) 533 if (i < (off_t)t->n) { 534 #endif 535 /* zero */ 536 ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0); 537 ATF_CHECK(ftello(fp) == len); 538 539 /* posive */ 540 for (i = (off_t)1; i <= rest; ++i) { 541 ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0); 542 ATF_CHECK(ftello(fp) == len + i); 543 } 544 545 /* positive + OOB */ 546 ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1); 547 ATF_CHECK(ftello(fp) == (off_t)t->n); 548 549 /* negative */ 550 for (i = (off_t)1; i <= (off_t)t->n; ++i) { 551 ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == 0); 552 ATF_CHECK(ftello(fp) == (off_t)t->n - i); 553 } 554 555 /* negative + OOB */ 556 ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1); 557 ATF_CHECK(ftello(fp) == (off_t)0); 558 559 #if defined(__GLIBC__) 560 } 561 #endif 562 ATF_CHECK(fclose(fp) == 0); 563 } 564 } 565 } 566 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 625 ATF_TC(test13); 626 ATF_TC_HEAD(test13, tc) 627 { 628 atf_tc_set_md_var(tc, "descr", "test13"); 629 } 630 ATF_TC_BODY(test13, tc) 631 { 632 struct testcase *t; 633 off_t len, rest, i; 634 const char **p; 635 char buf[BUFSIZ]; 636 FILE *fp; 637 638 /* test fmemopen_seek(SEEK_END) */ 639 for (t = &testcases[0]; t->s != NULL; ++t) { 640 len = (off_t)strnlen(t->s, t->n); 641 rest = t->n - len; 642 for (p = &mode_w[0]; *p != NULL; ++p) { 643 644 memcpy(buf, t->s, t->n); 645 fp = fmemopen(&buf[0], t->n, *p); 646 ATF_CHECK(fp != NULL); 647 /* 648 * test fmemopen_seek(SEEK_END) 649 */ 650 #if !defined(__GLIBC__) 651 ATF_CHECK(ftello(fp) == (off_t)0); 652 ATF_CHECK(buf[0] == '\0'); 653 654 /* zero */ 655 ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); 656 ATF_CHECK(ftello(fp) == (off_t)0); 657 658 /* positive + OOB */ 659 ATF_CHECK(fseeko(fp, (off_t)t->n + 1, SEEK_END) == -1); 660 ATF_CHECK(ftello(fp) == (off_t)0); 661 662 /* negative + OOB */ 663 ATF_CHECK(fseeko(fp, -1, SEEK_END) == -1); 664 ATF_CHECK(ftello(fp) == (off_t)0); 665 666 /* positive */ 667 for (i = 1; i <= t->n; ++i) { 668 ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); 669 ATF_CHECK(ftello(fp) == i); 670 } 671 #endif 672 ATF_CHECK(fclose(fp) == 0); 673 } 674 } 675 } 676 677 ATF_TC(test14); 678 ATF_TC_HEAD(test14, tc) 679 { 680 atf_tc_set_md_var(tc, "descr", "test14"); 681 } 682 ATF_TC_BODY(test14, tc) 683 { 684 struct testcase *t; 685 off_t len, rest, i; 686 const char **p; 687 char buf[BUFSIZ]; 688 FILE *fp; 689 690 /* test fmemopen_seek(SEEK_END) */ 691 for (t = &testcases[0]; t->s != NULL; ++t) { 692 len = (off_t)strnlen(t->s, t->n); 693 rest = (off_t)t->n - len; 694 for (p = &mode_a[0]; *p != NULL; ++p) { 695 696 memcpy(buf, t->s, t->n); 697 fp = fmemopen(&buf[0], t->n, *p); 698 ATF_CHECK(fp != NULL); 699 /* 700 * test fmemopen_seek(SEEK_END) 701 */ 702 #if !defined(__GLIBC__) 703 ATF_CHECK(ftello(fp) == len); 704 705 /* zero */ 706 ATF_CHECK(fseeko(fp, 0, SEEK_END) == 0); 707 ATF_CHECK(ftello(fp) == len); 708 709 /* positive + OOB */ 710 ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1); 711 ATF_CHECK(ftello(fp) == len); 712 713 /* negative + OOB */ 714 ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1); 715 ATF_CHECK(ftello(fp) == len); 716 717 /* positive */ 718 for (i = 1; i <= rest; ++i) { 719 ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); 720 ATF_CHECK(ftello(fp) == len + i); 721 } 722 723 /* negative */ 724 for (i = 1; i < len; ++i) { 725 ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0); 726 ATF_CHECK(ftello(fp) == len - i); 727 } 728 #endif 729 ATF_CHECK(fclose(fp) == 0); 730 } 731 } 732 } 733 734 const char *mode_rw1[] = { 735 "r", "rb", "r+", "rb+", "r+b", 736 "w+", "wb+", 737 NULL 738 }; 739 740 /* test15 - 18: 741 * When a stream open for writing is flushed or closed, a null byte is written 742 * at the current position or at the end of the buffer, depending on the size 743 * of the contents. 744 */ 745 746 ATF_TC(test15); 747 ATF_TC_HEAD(test15, tc) 748 { 749 atf_tc_set_md_var(tc, "descr", "test15"); 750 } 751 ATF_TC_BODY(test15, tc) 752 { 753 struct testcase *t; 754 const char **p; 755 char buf0[BUFSIZ]; 756 FILE *fp; 757 int i; 758 759 for (t = &testcases[0]; t->s != NULL; ++t) { 760 for (p = &mode_rw1[0]; *p != NULL; ++p) { 761 762 memcpy(&buf0[0], t->s, t->n); 763 fp = fmemopen(&buf0[0], t->n, *p); 764 ATF_CHECK(fp != NULL); 765 /* 766 * test fmemopen_read + fgetc(3) 767 */ 768 for (i = 0; i < t->n; ++i) { 769 ATF_CHECK(ftello(fp) == (off_t)i); 770 ATF_CHECK(fgetc(fp) == buf0[i]); 771 ATF_CHECK(feof(fp) == 0); 772 ATF_CHECK(ftello(fp) == (off_t)i + 1); 773 } 774 ATF_CHECK(fgetc(fp) == EOF); 775 ATF_CHECK(feof(fp) != 0); 776 ATF_CHECK(ftello(fp) == (off_t)t->n); 777 ATF_CHECK(fclose(fp) == 0); 778 } 779 } 780 } 781 782 ATF_TC(test16); 783 ATF_TC_HEAD(test16, tc) 784 { 785 atf_tc_set_md_var(tc, "descr", "test16"); 786 } 787 ATF_TC_BODY(test16, tc) 788 { 789 struct testcase *t; 790 const char **p; 791 char buf0[BUFSIZ], buf1[BUFSIZ]; 792 FILE *fp; 793 794 for (t = &testcases[0]; t->s != NULL; ++t) { 795 for (p = &mode_rw1[0]; *p != NULL; ++p) { 796 797 memcpy(&buf0[0], t->s, t->n); 798 buf1[t->n] = 0x1; 799 fp = fmemopen(&buf0[0], t->n, *p); 800 ATF_CHECK(fp != NULL); 801 /* 802 * test fmemopen_read + fread(4) 803 */ 804 ATF_CHECK(ftello(fp) == (off_t)0); 805 ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) == (size_t)t->n); 806 ATF_CHECK(feof(fp) != 0); 807 ATF_CHECK(memcmp(&buf0[0], &buf1[0], t->n) == 0); 808 ATF_CHECK((unsigned char)buf1[t->n] == 0x1); 809 810 ATF_CHECK(fclose(fp) == 0); 811 } 812 } 813 } 814 815 const char *mode_a1[] = { "a+", "ab+", NULL }; 816 817 ATF_TC(test17); 818 ATF_TC_HEAD(test17, tc) 819 { 820 atf_tc_set_md_var(tc, "descr", "test17"); 821 } 822 ATF_TC_BODY(test17, tc) 823 { 824 struct testcase *t; 825 size_t len; 826 int i; 827 const char **p; 828 char buf[BUFSIZ]; 829 FILE *fp; 830 831 for (t = &testcases[0]; t->s != NULL; ++t) { 832 len = strnlen(t->s, t->n); 833 for (p = &mode_a1[0]; *p != NULL; ++p) { 834 835 memcpy(&buf[0], t->s, t->n); 836 fp = fmemopen(&buf[0], t->n, *p); 837 ATF_CHECK(fp != NULL); 838 /* 839 * test fmemopen_read + fgetc(3) 840 */ 841 #if defined(__GLIBC__) 842 if (i < t->n) { 843 #endif 844 for (i = len; i < t->n; ++i) { 845 ATF_CHECK(ftello(fp) == (off_t)i); 846 ATF_CHECK(fgetc(fp) == buf[i]); 847 ATF_CHECK(feof(fp) == 0); 848 ATF_CHECK(ftello(fp) == (off_t)i + 1); 849 } 850 ATF_CHECK(fgetc(fp) == EOF); 851 ATF_CHECK(feof(fp) != 0); 852 ATF_CHECK(ftello(fp) == (off_t)t->n); 853 rewind(fp); 854 for (i = 0; i < t->n; ++i) { 855 ATF_CHECK(ftello(fp) == (off_t)i); 856 ATF_CHECK(fgetc(fp) == buf[i]); 857 ATF_CHECK(feof(fp) == 0); 858 ATF_CHECK(ftello(fp) == (off_t)i + 1); 859 } 860 ATF_CHECK(fgetc(fp) == EOF); 861 ATF_CHECK(feof(fp) != 0); 862 ATF_CHECK(ftello(fp) == (off_t)t->n); 863 #if defined(__GLIBC__) 864 } 865 #endif 866 ATF_CHECK(fclose(fp) == 0); 867 } 868 } 869 } 870 871 ATF_TC(test18); 872 ATF_TC_HEAD(test18, tc) 873 { 874 atf_tc_set_md_var(tc, "descr", "test18"); 875 } 876 ATF_TC_BODY(test18, tc) 877 { 878 struct testcase *t; 879 size_t len; 880 const char **p; 881 char buf0[BUFSIZ], buf1[BUFSIZ]; 882 FILE *fp; 883 884 for (t = &testcases[0]; t->s != NULL; ++t) { 885 len = strnlen(t->s, t->n); 886 for (p = &mode_a1[0]; *p != NULL; ++p) { 887 888 memcpy(&buf0[0], t->s, t->n); 889 buf1[t->n - len] = 0x1; 890 fp = fmemopen(&buf0[0], t->n, *p); 891 ATF_CHECK(fp != NULL); 892 /* 893 * test fmemopen_read + fread(3) 894 */ 895 #if defined(__GLIBC__) 896 if (i < t->n) { 897 #endif 898 ATF_CHECK(ftello(fp) == (off_t)len); 899 ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) 900 == t->n - len); 901 ATF_CHECK(feof(fp) != 0); 902 ATF_CHECK(!memcmp(&buf0[len], &buf1[0], t->n - len)); 903 ATF_CHECK((unsigned char)buf1[t->n - len] == 0x1); 904 rewind(fp); 905 buf1[t->n] = 0x1; 906 ATF_CHECK(ftello(fp) == (off_t)0); 907 ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) 908 == (size_t)t->n); 909 ATF_CHECK(feof(fp) != 0); 910 ATF_CHECK(!memcmp(&buf0[0], &buf1[0], t->n)); 911 ATF_CHECK((unsigned char)buf1[t->n] == 0x1); 912 #if defined(__GLIBC__) 913 } 914 #endif 915 ATF_CHECK(fclose(fp) == 0); 916 } 917 } 918 } 919 920 /* 921 * test19 - test22: 922 * If a stream open for update is flushed or closed and the last write has 923 * advanced the current buffer size, a null byte is written at the end of the 924 * buffer if it fits. 925 */ 926 927 const char *mode_rw2[] = { 928 "r+", "rb+", "r+b", 929 "w", "wb", "w+", "wb+", "w+b", 930 NULL 931 }; 932 933 ATF_TC(test19); 934 ATF_TC_HEAD(test19, tc) 935 { 936 atf_tc_set_md_var(tc, "descr", "test19"); 937 } 938 ATF_TC_BODY(test19, tc) 939 { 940 struct testcase *t; 941 size_t len; 942 int i; 943 const char **p; 944 char buf[BUFSIZ]; 945 FILE *fp; 946 947 for (t = &testcases[0]; t->s != NULL; ++t) { 948 len = strnlen(t->s, t->n); 949 for (p = &mode_rw2[0]; *p != NULL; ++p) { 950 951 memcpy(&buf[0], t->s, t->n); 952 buf[t->n] = 0x1; 953 fp = fmemopen(&buf[0], t->n + 1, *p); 954 ATF_CHECK(fp != NULL); 955 setbuf(fp, NULL); 956 /* 957 * test fmemopen_write + fputc(3) 958 */ 959 for (i = 0; i < t->n; ++i) { 960 ATF_CHECK(ftello(fp) == (off_t)i); 961 ATF_CHECK(fputc(t->s[i], fp) == t->s[i]); 962 ATF_CHECK(buf[i] == t->s[i]); 963 ATF_CHECK(ftello(fp) == (off_t)i + 1); 964 ATF_CHECK(buf[i] == t->s[i]); 965 #if !defined(__GLIBC__) 966 ATF_CHECK(buf[i + 1] == '\0'); 967 #endif 968 } 969 970 /* don't accept non nul character at end of buffer */ 971 ATF_CHECK(fputc(0x1, fp) == EOF); 972 ATF_CHECK(ftello(fp) == (off_t)t->n); 973 ATF_CHECK(feof(fp) == 0); 974 975 /* accept nul character at end of buffer */ 976 ATF_CHECK(fputc('\0', fp) == '\0'); 977 ATF_CHECK(ftello(fp) == (off_t)t->n + 1); 978 ATF_CHECK(feof(fp) == 0); 979 980 /* reach EOF */ 981 ATF_CHECK(fputc('\0', fp) == EOF); 982 ATF_CHECK(ftello(fp) == (off_t)t->n + 1); 983 984 /* compare */ 985 ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0); 986 ATF_CHECK(buf[t->n] == '\0'); 987 988 ATF_CHECK(fclose(fp) == 0); 989 } 990 } 991 } 992 993 ATF_TC(test20); 994 ATF_TC_HEAD(test20, tc) 995 { 996 atf_tc_set_md_var(tc, "descr", "test20"); 997 } 998 ATF_TC_BODY(test20, tc) 999 { 1000 struct testcase *t; 1001 size_t len; 1002 const char **p; 1003 char buf[BUFSIZ]; 1004 FILE *fp; 1005 1006 for (t = &testcases[0]; t->s != NULL; ++t) { 1007 len = strnlen(t->s, t->n); 1008 for (p = &mode_rw2[0]; *p != NULL; ++p) { 1009 1010 memcpy(&buf[0], t->s, t->n); 1011 buf[t->n] = 0x1; 1012 fp = fmemopen(&buf[0], t->n + 1, *p); 1013 ATF_CHECK(fp != NULL); 1014 setbuf(fp, NULL); 1015 ATF_CHECK(fwrite(t->s, 1, t->n, fp) == (size_t)t->n); 1016 /* 1017 * test fmemopen_write + fwrite(3) 1018 */ 1019 #if !defined(__GLIBC__) 1020 ATF_CHECK(buf[t->n] == '\0'); 1021 1022 /* don't accept non nul character at end of buffer */ 1023 ATF_CHECK(fwrite("\x1", 1, 1, fp) == 0); 1024 ATF_CHECK(ftello(fp) == (off_t)t->n); 1025 ATF_CHECK(feof(fp) == 0); 1026 #endif 1027 1028 /* accept nul character at end of buffer */ 1029 ATF_CHECK(fwrite("\x0", 1, 1, fp) == 1); 1030 ATF_CHECK(ftello(fp) == (off_t)t->n + 1); 1031 ATF_CHECK(feof(fp) == 0); 1032 1033 /* reach EOF */ 1034 ATF_CHECK(fputc('\0', fp) == EOF); 1035 ATF_CHECK(ftello(fp) == (off_t)t->n + 1); 1036 1037 /* compare */ 1038 ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0); 1039 ATF_CHECK(buf[t->n] == '\0'); 1040 1041 ATF_CHECK(fclose(fp) == 0); 1042 } 1043 } 1044 } 1045 1046 ATF_TC(test21); 1047 ATF_TC_HEAD(test21, tc) 1048 { 1049 atf_tc_set_md_var(tc, "descr", "test21"); 1050 } 1051 ATF_TC_BODY(test21, tc) 1052 { 1053 struct testcase *t; 1054 int len, i; 1055 const char **p; 1056 char buf[BUFSIZ]; 1057 FILE *fp; 1058 1059 for (t = &testcases[0]; t->s != NULL; ++t) { 1060 len = strnlen(t->s, t->n); 1061 for (p = &mode_a[0]; *p != NULL; ++p) { 1062 memcpy(&buf[0], t->s, t->n); 1063 fp = fmemopen(&buf[0], t->n, *p); 1064 ATF_CHECK(fp != NULL); 1065 setbuf(fp, NULL); 1066 /* 1067 * test fmemopen_write + fputc(3) 1068 */ 1069 if (len < t->n) { 1070 for (i = len; i < t->n - 1; ++i) { 1071 ATF_CHECK(ftello(fp) == (off_t)i); 1072 ATF_CHECK(fputc(t->s[i - len], fp) 1073 == t->s[i - len]); 1074 ATF_CHECK(buf[i] == t->s[i - len]); 1075 ATF_CHECK(ftello(fp) == (off_t)i + 1); 1076 #if !defined(__GLIBC__) 1077 ATF_CHECK(buf[i + 1] == '\0'); 1078 #endif 1079 } 1080 1081 /* don't accept non nul character at end of buffer */ 1082 ATF_CHECK(ftello(fp) == (off_t)t->n - 1); 1083 ATF_CHECK(fputc(0x1, fp) == EOF); 1084 ATF_CHECK(ftello(fp) == (off_t)t->n - 1); 1085 1086 /* accept nul character at end of buffer */ 1087 ATF_CHECK(ftello(fp) == (off_t)t->n - 1); 1088 ATF_CHECK(fputc('\0', fp) == '\0'); 1089 ATF_CHECK(ftello(fp) == (off_t)t->n); 1090 } 1091 1092 /* reach EOF */ 1093 ATF_CHECK(ftello(fp) == (off_t)t->n); 1094 ATF_CHECK(fputc('\0', fp) == EOF); 1095 ATF_CHECK(ftello(fp) == (off_t)t->n); 1096 1097 ATF_CHECK(fclose(fp) == 0); 1098 } 1099 } 1100 } 1101 1102 ATF_TC(test22); 1103 ATF_TC_HEAD(test22, tc) 1104 { 1105 atf_tc_set_md_var(tc, "descr", "test22"); 1106 } 1107 ATF_TC_BODY(test22, tc) 1108 { 1109 struct testcase *t0, *t1; 1110 size_t len0, len1, nleft; 1111 const char **p; 1112 char buf[BUFSIZ]; 1113 FILE *fp; 1114 1115 for (t0 = &testcases[0]; t0->s != NULL; ++t0) { 1116 len0 = strnlen(t0->s, t0->n); 1117 for (t1 = &testcases[0]; t1->s != NULL; ++t1) { 1118 len1 = strnlen(t1->s, t1->n); 1119 for (p = &mode_a[0]; *p != NULL; ++p) { 1120 1121 memcpy(&buf[0], t0->s, t0->n); 1122 fp = fmemopen(&buf[0], t0->n, *p); 1123 ATF_CHECK(fp != NULL); 1124 setbuf(fp, NULL); 1125 /* 1126 * test fmemopen_write + fwrite(3) 1127 */ 1128 nleft = t0->n - len0; 1129 #if !defined(__GLIBC__) 1130 if (nleft == 0 || len1 == nleft - 1) { 1131 ATF_CHECK(fwrite(t1->s, 1, t1->n, fp) 1132 == nleft); 1133 ATF_CHECK(ftell(fp) == t1->n); 1134 } else { 1135 ATF_CHECK(fwrite(t1->s, 1, t1->n, fp) 1136 == nleft - 1); 1137 ATF_CHECK(ftell(fp) == t1->n - 1); 1138 } 1139 #endif 1140 ATF_CHECK(fclose(fp) == 0); 1141 } 1142 } 1143 } 1144 } 1145 1146 ATF_TP_ADD_TCS(tp) 1147 { 1148 ATF_TP_ADD_TC(tp, test00); 1149 ATF_TP_ADD_TC(tp, test01); 1150 ATF_TP_ADD_TC(tp, test02); 1151 ATF_TP_ADD_TC(tp, test03); 1152 ATF_TP_ADD_TC(tp, test04); 1153 ATF_TP_ADD_TC(tp, test05); 1154 ATF_TP_ADD_TC(tp, test06); 1155 ATF_TP_ADD_TC(tp, test07); 1156 ATF_TP_ADD_TC(tp, test08); 1157 ATF_TP_ADD_TC(tp, test09); 1158 ATF_TP_ADD_TC(tp, test10); 1159 ATF_TP_ADD_TC(tp, test11); 1160 ATF_TP_ADD_TC(tp, test12); 1161 ATF_TP_ADD_TC(tp, test13); 1162 ATF_TP_ADD_TC(tp, test14); 1163 ATF_TP_ADD_TC(tp, test15); 1164 ATF_TP_ADD_TC(tp, test16); 1165 ATF_TP_ADD_TC(tp, test17); 1166 ATF_TP_ADD_TC(tp, test18); 1167 ATF_TP_ADD_TC(tp, test19); 1168 ATF_TP_ADD_TC(tp, test20); 1169 ATF_TP_ADD_TC(tp, test21); 1170 ATF_TP_ADD_TC(tp, test22); 1171 1172 return atf_no_error(); 1173 } 1174