stdio_test.cpp revision 20841a137beac5caa824e3586c7bd91d879ff92e
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <gtest/gtest.h> 18 19#include <errno.h> 20#include <fcntl.h> 21#include <limits.h> 22#include <math.h> 23#include <stdio.h> 24#include <sys/types.h> 25#include <sys/stat.h> 26#include <unistd.h> 27#include <wchar.h> 28#include <locale.h> 29 30#include "TemporaryFile.h" 31 32TEST(stdio, flockfile_18208568_stderr) { 33 // Check that we have a _recursive_ mutex for flockfile. 34 flockfile(stderr); 35 feof(stderr); // We don't care about the result, but this needs to take the lock. 36 funlockfile(stderr); 37} 38 39TEST(stdio, flockfile_18208568_regular) { 40 // We never had a bug for streams other than stdin/stdout/stderr, but test anyway. 41 FILE* fp = fopen("/dev/null", "w"); 42 ASSERT_TRUE(fp != NULL); 43 flockfile(fp); 44 feof(fp); 45 funlockfile(fp); 46 fclose(fp); 47} 48 49TEST(stdio, tmpfile_fileno_fprintf_rewind_fgets) { 50 FILE* fp = tmpfile(); 51 ASSERT_TRUE(fp != NULL); 52 53 int fd = fileno(fp); 54 ASSERT_NE(fd, -1); 55 56 struct stat sb; 57 int rc = fstat(fd, &sb); 58 ASSERT_NE(rc, -1); 59 ASSERT_EQ(sb.st_mode & 0777, 0600U); 60 61 rc = fprintf(fp, "hello\n"); 62 ASSERT_EQ(rc, 6); 63 64 rewind(fp); 65 66 char buf[16]; 67 char* s = fgets(buf, sizeof(buf), fp); 68 ASSERT_TRUE(s != NULL); 69 ASSERT_STREQ("hello\n", s); 70 71 fclose(fp); 72} 73 74TEST(stdio, dprintf) { 75 TemporaryFile tf; 76 77 int rc = dprintf(tf.fd, "hello\n"); 78 ASSERT_EQ(rc, 6); 79 80 lseek(tf.fd, 0, SEEK_SET); 81 FILE* tfile = fdopen(tf.fd, "r"); 82 ASSERT_TRUE(tfile != NULL); 83 84 char buf[7]; 85 ASSERT_EQ(buf, fgets(buf, sizeof(buf), tfile)); 86 ASSERT_STREQ("hello\n", buf); 87 // Make sure there isn't anything else in the file. 88 ASSERT_EQ(NULL, fgets(buf, sizeof(buf), tfile)); 89 fclose(tfile); 90} 91 92TEST(stdio, getdelim) { 93 FILE* fp = tmpfile(); 94 ASSERT_TRUE(fp != NULL); 95 96 const char* line_written = "This is a test"; 97 int rc = fprintf(fp, "%s", line_written); 98 ASSERT_EQ(rc, static_cast<int>(strlen(line_written))); 99 100 rewind(fp); 101 102 char* word_read = NULL; 103 size_t allocated_length = 0; 104 105 const char* expected[] = { "This ", " ", "is ", "a ", "test" }; 106 for (size_t i = 0; i < 5; ++i) { 107 ASSERT_FALSE(feof(fp)); 108 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), static_cast<int>(strlen(expected[i]))); 109 ASSERT_GE(allocated_length, strlen(expected[i])); 110 ASSERT_STREQ(word_read, expected[i]); 111 } 112 // The last read should have set the end-of-file indicator for the stream. 113 ASSERT_TRUE(feof(fp)); 114 clearerr(fp); 115 116 // getdelim returns -1 but doesn't set errno if we're already at EOF. 117 // It should set the end-of-file indicator for the stream, though. 118 errno = 0; 119 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), -1); 120 ASSERT_EQ(0, errno); 121 ASSERT_TRUE(feof(fp)); 122 123 free(word_read); 124 fclose(fp); 125} 126 127TEST(stdio, getdelim_invalid) { 128 FILE* fp = tmpfile(); 129 ASSERT_TRUE(fp != NULL); 130 131 char* buffer = NULL; 132 size_t buffer_length = 0; 133 134 // The first argument can't be NULL. 135 errno = 0; 136 ASSERT_EQ(getdelim(NULL, &buffer_length, ' ', fp), -1); 137 ASSERT_EQ(EINVAL, errno); 138 139 // The second argument can't be NULL. 140 errno = 0; 141 ASSERT_EQ(getdelim(&buffer, NULL, ' ', fp), -1); 142 ASSERT_EQ(EINVAL, errno); 143 144 // The underlying fd can't be closed. 145 ASSERT_EQ(0, close(fileno(fp))); 146 errno = 0; 147 ASSERT_EQ(getdelim(&buffer, &buffer_length, ' ', fp), -1); 148 ASSERT_EQ(EBADF, errno); 149 fclose(fp); 150} 151 152TEST(stdio, getline) { 153 FILE* fp = tmpfile(); 154 ASSERT_TRUE(fp != NULL); 155 156 const char* line_written = "This is a test for getline\n"; 157 const size_t line_count = 5; 158 159 for (size_t i = 0; i < line_count; ++i) { 160 int rc = fprintf(fp, "%s", line_written); 161 ASSERT_EQ(rc, static_cast<int>(strlen(line_written))); 162 } 163 164 rewind(fp); 165 166 char* line_read = NULL; 167 size_t allocated_length = 0; 168 169 size_t read_line_count = 0; 170 ssize_t read_char_count; 171 while ((read_char_count = getline(&line_read, &allocated_length, fp)) != -1) { 172 ASSERT_EQ(read_char_count, static_cast<int>(strlen(line_written))); 173 ASSERT_GE(allocated_length, strlen(line_written)); 174 ASSERT_STREQ(line_read, line_written); 175 ++read_line_count; 176 } 177 ASSERT_EQ(read_line_count, line_count); 178 179 // The last read should have set the end-of-file indicator for the stream. 180 ASSERT_TRUE(feof(fp)); 181 clearerr(fp); 182 183 // getline returns -1 but doesn't set errno if we're already at EOF. 184 // It should set the end-of-file indicator for the stream, though. 185 errno = 0; 186 ASSERT_EQ(getline(&line_read, &allocated_length, fp), -1); 187 ASSERT_EQ(0, errno); 188 ASSERT_TRUE(feof(fp)); 189 190 free(line_read); 191 fclose(fp); 192} 193 194TEST(stdio, getline_invalid) { 195 FILE* fp = tmpfile(); 196 ASSERT_TRUE(fp != NULL); 197 198 char* buffer = NULL; 199 size_t buffer_length = 0; 200 201 // The first argument can't be NULL. 202 errno = 0; 203 ASSERT_EQ(getline(NULL, &buffer_length, fp), -1); 204 ASSERT_EQ(EINVAL, errno); 205 206 // The second argument can't be NULL. 207 errno = 0; 208 ASSERT_EQ(getline(&buffer, NULL, fp), -1); 209 ASSERT_EQ(EINVAL, errno); 210 211 // The underlying fd can't be closed. 212 ASSERT_EQ(0, close(fileno(fp))); 213 errno = 0; 214 ASSERT_EQ(getline(&buffer, &buffer_length, fp), -1); 215 ASSERT_EQ(EBADF, errno); 216 fclose(fp); 217} 218 219TEST(stdio, printf_ssize_t) { 220 // http://b/8253769 221 ASSERT_EQ(sizeof(ssize_t), sizeof(long int)); 222 ASSERT_EQ(sizeof(ssize_t), sizeof(size_t)); 223 // For our 32-bit ABI, we had a ssize_t definition that confuses GCC into saying: 224 // error: format '%zd' expects argument of type 'signed size_t', 225 // but argument 4 has type 'ssize_t {aka long int}' [-Werror=format] 226 ssize_t v = 1; 227 char buf[32]; 228 snprintf(buf, sizeof(buf), "%zd", v); 229} 230 231// https://code.google.com/p/android/issues/detail?id=64886 232TEST(stdio, snprintf_a) { 233 char buf[BUFSIZ]; 234 EXPECT_EQ(23, snprintf(buf, sizeof(buf), "<%a>", 9990.235)); 235 EXPECT_STREQ("<0x1.3831e147ae148p+13>", buf); 236} 237 238TEST(stdio, snprintf_lc) { 239 char buf[BUFSIZ]; 240 wint_t wc = L'a'; 241 EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%lc>", wc)); 242 EXPECT_STREQ("<a>", buf); 243} 244 245TEST(stdio, snprintf_ls) { 246 char buf[BUFSIZ]; 247 wchar_t* ws = NULL; 248 EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%ls>", ws)); 249 EXPECT_STREQ("<(null)>", buf); 250 251 wchar_t chars[] = { L'h', L'i', 0 }; 252 ws = chars; 253 EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%ls>", ws)); 254 EXPECT_STREQ("<hi>", buf); 255} 256 257TEST(stdio, snprintf_n) { 258#if defined(__BIONIC__) 259 // http://b/14492135 260 char buf[32]; 261 int i = 1234; 262 EXPECT_EQ(5, snprintf(buf, sizeof(buf), "a %n b", &i)); 263 EXPECT_EQ(1234, i); 264 EXPECT_STREQ("a n b", buf); 265#else 266 GTEST_LOG_(INFO) << "This test does nothing.\n"; 267#endif 268} 269 270TEST(stdio, snprintf_smoke) { 271 char buf[BUFSIZ]; 272 273 snprintf(buf, sizeof(buf), "a"); 274 EXPECT_STREQ("a", buf); 275 276 snprintf(buf, sizeof(buf), "%%"); 277 EXPECT_STREQ("%", buf); 278 279 snprintf(buf, sizeof(buf), "01234"); 280 EXPECT_STREQ("01234", buf); 281 282 snprintf(buf, sizeof(buf), "a%sb", "01234"); 283 EXPECT_STREQ("a01234b", buf); 284 285 char* s = NULL; 286 snprintf(buf, sizeof(buf), "a%sb", s); 287 EXPECT_STREQ("a(null)b", buf); 288 289 snprintf(buf, sizeof(buf), "aa%scc", "bb"); 290 EXPECT_STREQ("aabbcc", buf); 291 292 snprintf(buf, sizeof(buf), "a%cc", 'b'); 293 EXPECT_STREQ("abc", buf); 294 295 snprintf(buf, sizeof(buf), "a%db", 1234); 296 EXPECT_STREQ("a1234b", buf); 297 298 snprintf(buf, sizeof(buf), "a%db", -8123); 299 EXPECT_STREQ("a-8123b", buf); 300 301 snprintf(buf, sizeof(buf), "a%hdb", static_cast<short>(0x7fff0010)); 302 EXPECT_STREQ("a16b", buf); 303 304 snprintf(buf, sizeof(buf), "a%hhdb", static_cast<char>(0x7fffff10)); 305 EXPECT_STREQ("a16b", buf); 306 307 snprintf(buf, sizeof(buf), "a%lldb", 0x1000000000LL); 308 EXPECT_STREQ("a68719476736b", buf); 309 310 snprintf(buf, sizeof(buf), "a%ldb", 70000L); 311 EXPECT_STREQ("a70000b", buf); 312 313 snprintf(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234)); 314 EXPECT_STREQ("a0xb0001234b", buf); 315 316 snprintf(buf, sizeof(buf), "a%xz", 0x12ab); 317 EXPECT_STREQ("a12abz", buf); 318 319 snprintf(buf, sizeof(buf), "a%Xz", 0x12ab); 320 EXPECT_STREQ("a12ABz", buf); 321 322 snprintf(buf, sizeof(buf), "a%08xz", 0x123456); 323 EXPECT_STREQ("a00123456z", buf); 324 325 snprintf(buf, sizeof(buf), "a%5dz", 1234); 326 EXPECT_STREQ("a 1234z", buf); 327 328 snprintf(buf, sizeof(buf), "a%05dz", 1234); 329 EXPECT_STREQ("a01234z", buf); 330 331 snprintf(buf, sizeof(buf), "a%8dz", 1234); 332 EXPECT_STREQ("a 1234z", buf); 333 334 snprintf(buf, sizeof(buf), "a%-8dz", 1234); 335 EXPECT_STREQ("a1234 z", buf); 336 337 snprintf(buf, sizeof(buf), "A%-11sZ", "abcdef"); 338 EXPECT_STREQ("Aabcdef Z", buf); 339 340 snprintf(buf, sizeof(buf), "A%s:%dZ", "hello", 1234); 341 EXPECT_STREQ("Ahello:1234Z", buf); 342 343 snprintf(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5); 344 EXPECT_STREQ("a005:5:05z", buf); 345 346 void* p = NULL; 347 snprintf(buf, sizeof(buf), "a%d,%pz", 5, p); 348#if defined(__BIONIC__) 349 EXPECT_STREQ("a5,0x0z", buf); 350#else // __BIONIC__ 351 EXPECT_STREQ("a5,(nil)z", buf); 352#endif // __BIONIC__ 353 354 snprintf(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8); 355 EXPECT_STREQ("a68719476736,6,7,8z", buf); 356 357 snprintf(buf, sizeof(buf), "a_%f_b", 1.23f); 358 EXPECT_STREQ("a_1.230000_b", buf); 359 360 snprintf(buf, sizeof(buf), "a_%g_b", 3.14); 361 EXPECT_STREQ("a_3.14_b", buf); 362 363 snprintf(buf, sizeof(buf), "%1$s %1$s", "print_me_twice"); 364 EXPECT_STREQ("print_me_twice print_me_twice", buf); 365} 366 367TEST(stdio, snprintf_f_special) { 368 char buf[BUFSIZ]; 369 snprintf(buf, sizeof(buf), "%f", nanf("")); 370 EXPECT_STRCASEEQ("NaN", buf); 371 372 snprintf(buf, sizeof(buf), "%f", HUGE_VALF); 373 EXPECT_STRCASEEQ("Inf", buf); 374} 375 376TEST(stdio, snprintf_g_special) { 377 char buf[BUFSIZ]; 378 snprintf(buf, sizeof(buf), "%g", nan("")); 379 EXPECT_STRCASEEQ("NaN", buf); 380 381 snprintf(buf, sizeof(buf), "%g", HUGE_VAL); 382 EXPECT_STRCASEEQ("Inf", buf); 383} 384 385TEST(stdio, snprintf_d_INT_MAX) { 386 char buf[BUFSIZ]; 387 snprintf(buf, sizeof(buf), "%d", INT_MAX); 388 EXPECT_STREQ("2147483647", buf); 389} 390 391TEST(stdio, snprintf_d_INT_MIN) { 392 char buf[BUFSIZ]; 393 snprintf(buf, sizeof(buf), "%d", INT_MIN); 394 EXPECT_STREQ("-2147483648", buf); 395} 396 397TEST(stdio, snprintf_ld_LONG_MAX) { 398 char buf[BUFSIZ]; 399 snprintf(buf, sizeof(buf), "%ld", LONG_MAX); 400#if __LP64__ 401 EXPECT_STREQ("9223372036854775807", buf); 402#else 403 EXPECT_STREQ("2147483647", buf); 404#endif 405} 406 407TEST(stdio, snprintf_ld_LONG_MIN) { 408 char buf[BUFSIZ]; 409 snprintf(buf, sizeof(buf), "%ld", LONG_MIN); 410#if __LP64__ 411 EXPECT_STREQ("-9223372036854775808", buf); 412#else 413 EXPECT_STREQ("-2147483648", buf); 414#endif 415} 416 417TEST(stdio, snprintf_lld_LLONG_MAX) { 418 char buf[BUFSIZ]; 419 snprintf(buf, sizeof(buf), "%lld", LLONG_MAX); 420 EXPECT_STREQ("9223372036854775807", buf); 421} 422 423TEST(stdio, snprintf_lld_LLONG_MIN) { 424 char buf[BUFSIZ]; 425 snprintf(buf, sizeof(buf), "%lld", LLONG_MIN); 426 EXPECT_STREQ("-9223372036854775808", buf); 427} 428 429TEST(stdio, snprintf_e) { 430 char buf[BUFSIZ]; 431 432 snprintf(buf, sizeof(buf), "%e", 1.5); 433 EXPECT_STREQ("1.500000e+00", buf); 434 435 snprintf(buf, sizeof(buf), "%Le", 1.5l); 436 EXPECT_STREQ("1.500000e+00", buf); 437} 438 439TEST(stdio, snprintf_negative_zero_5084292) { 440 char buf[BUFSIZ]; 441 442 snprintf(buf, sizeof(buf), "%f", -0.0); 443 EXPECT_STREQ("-0.000000", buf); 444} 445 446TEST(stdio, snprintf_utf8_15439554) { 447 locale_t cloc = newlocale(LC_ALL, "C.UTF-8", 0); 448 locale_t old_locale = uselocale(cloc); 449 450 // http://b/15439554 451 char buf[BUFSIZ]; 452 453 // 1-byte character. 454 snprintf(buf, sizeof(buf), "%dx%d", 1, 2); 455 EXPECT_STREQ("1x2", buf); 456 // 2-byte character. 457 snprintf(buf, sizeof(buf), "%d\xc2\xa2%d", 1, 2); 458 EXPECT_STREQ("1¢2", buf); 459 // 3-byte character. 460 snprintf(buf, sizeof(buf), "%d\xe2\x82\xac%d", 1, 2); 461 EXPECT_STREQ("1€2", buf); 462 // 4-byte character. 463 snprintf(buf, sizeof(buf), "%d\xf0\xa4\xad\xa2%d", 1, 2); 464 EXPECT_STREQ("12", buf); 465 466 uselocale(old_locale); 467 freelocale(cloc); 468} 469 470TEST(stdio, fprintf_failures_7229520) { 471 // http://b/7229520 472 FILE* fp; 473 474 // Unbuffered case where the fprintf(3) itself fails. 475 ASSERT_NE(nullptr, fp = tmpfile()); 476 setbuf(fp, NULL); 477 ASSERT_EQ(4, fprintf(fp, "epic")); 478 ASSERT_EQ(0, close(fileno(fp))); 479 ASSERT_EQ(-1, fprintf(fp, "fail")); 480 ASSERT_EQ(-1, fclose(fp)); 481 482 // Buffered case where we won't notice until the fclose(3). 483 // It's likely this is what was actually seen in http://b/7229520, 484 // and that expecting fprintf to fail is setting yourself up for 485 // disappointment. Remember to check fclose(3)'s return value, kids! 486 ASSERT_NE(nullptr, fp = tmpfile()); 487 ASSERT_EQ(4, fprintf(fp, "epic")); 488 ASSERT_EQ(0, close(fileno(fp))); 489 ASSERT_EQ(4, fprintf(fp, "fail")); 490 ASSERT_EQ(-1, fclose(fp)); 491} 492 493TEST(stdio, popen) { 494 FILE* fp = popen("cat /proc/version", "r"); 495 ASSERT_TRUE(fp != NULL); 496 497 char buf[16]; 498 char* s = fgets(buf, sizeof(buf), fp); 499 buf[13] = '\0'; 500 ASSERT_STREQ("Linux version", s); 501 502 ASSERT_EQ(0, pclose(fp)); 503} 504 505TEST(stdio, getc) { 506 FILE* fp = fopen("/proc/version", "r"); 507 ASSERT_TRUE(fp != NULL); 508 ASSERT_EQ('L', getc(fp)); 509 ASSERT_EQ('i', getc(fp)); 510 ASSERT_EQ('n', getc(fp)); 511 ASSERT_EQ('u', getc(fp)); 512 ASSERT_EQ('x', getc(fp)); 513 fclose(fp); 514} 515 516TEST(stdio, putc) { 517 FILE* fp = fopen("/proc/version", "r"); 518 ASSERT_TRUE(fp != NULL); 519 ASSERT_EQ(EOF, putc('x', fp)); 520 fclose(fp); 521} 522 523TEST(stdio, sscanf) { 524 char s1[123]; 525 int i1; 526 double d1; 527 char s2[123]; 528 ASSERT_EQ(3, sscanf(" hello 123 1.23 ", "%s %i %lf %s", s1, &i1, &d1, s2)); 529 ASSERT_STREQ("hello", s1); 530 ASSERT_EQ(123, i1); 531 ASSERT_DOUBLE_EQ(1.23, d1); 532} 533 534TEST(stdio, cantwrite_EBADF) { 535 // If we open a file read-only... 536 FILE* fp = fopen("/proc/version", "r"); 537 538 // ...all attempts to write to that file should return failure. 539 540 // They should also set errno to EBADF. This isn't POSIX, but it's traditional. 541 // glibc gets the wide-character functions wrong. 542 543 errno = 0; 544 EXPECT_EQ(EOF, putc('x', fp)); 545 EXPECT_EQ(EBADF, errno); 546 547 errno = 0; 548 EXPECT_EQ(EOF, fprintf(fp, "hello")); 549 EXPECT_EQ(EBADF, errno); 550 551 errno = 0; 552 EXPECT_EQ(EOF, fwprintf(fp, L"hello")); 553#if defined(__BIONIC__) 554 EXPECT_EQ(EBADF, errno); 555#endif 556 557 errno = 0; 558 EXPECT_EQ(0U, fwrite("hello", 1, 2, fp)); 559 EXPECT_EQ(EBADF, errno); 560 561 errno = 0; 562 EXPECT_EQ(EOF, fputs("hello", fp)); 563 EXPECT_EQ(EBADF, errno); 564 565 errno = 0; 566 EXPECT_EQ(WEOF, fputwc(L'x', fp)); 567#if defined(__BIONIC__) 568 EXPECT_EQ(EBADF, errno); 569#endif 570} 571 572// Tests that we can only have a consistent and correct fpos_t when using 573// f*pos functions (i.e. fpos doesn't get inside a multi byte character). 574TEST(stdio, consistent_fpos_t) { 575 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 576 uselocale(LC_GLOBAL_LOCALE); 577 578 FILE* fp = tmpfile(); 579 ASSERT_TRUE(fp != NULL); 580 581 wchar_t mb_one_bytes = L'h'; 582 wchar_t mb_two_bytes = 0x00a2; 583 wchar_t mb_three_bytes = 0x20ac; 584 wchar_t mb_four_bytes = 0x24b62; 585 586 // Write to file. 587 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fputwc(mb_one_bytes, fp))); 588 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp))); 589 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp))); 590 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp))); 591 592 rewind(fp); 593 594 // Record each character position. 595 fpos_t pos1; 596 fpos_t pos2; 597 fpos_t pos3; 598 fpos_t pos4; 599 fpos_t pos5; 600 EXPECT_EQ(0, fgetpos(fp, &pos1)); 601 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp))); 602 EXPECT_EQ(0, fgetpos(fp, &pos2)); 603 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp))); 604 EXPECT_EQ(0, fgetpos(fp, &pos3)); 605 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp))); 606 EXPECT_EQ(0, fgetpos(fp, &pos4)); 607 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp))); 608 EXPECT_EQ(0, fgetpos(fp, &pos5)); 609 610#if defined(__BIONIC__) 611 // Bionic's fpos_t is just an alias for off_t. This is inherited from OpenBSD 612 // upstream. Glibc differs by storing the mbstate_t inside its fpos_t. In 613 // Bionic (and upstream OpenBSD) the mbstate_t is stored inside the FILE 614 // structure. 615 ASSERT_EQ(0, static_cast<off_t>(pos1)); 616 ASSERT_EQ(1, static_cast<off_t>(pos2)); 617 ASSERT_EQ(3, static_cast<off_t>(pos3)); 618 ASSERT_EQ(6, static_cast<off_t>(pos4)); 619 ASSERT_EQ(10, static_cast<off_t>(pos5)); 620#endif 621 622 // Exercise back and forth movements of the position. 623 ASSERT_EQ(0, fsetpos(fp, &pos2)); 624 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp))); 625 ASSERT_EQ(0, fsetpos(fp, &pos1)); 626 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp))); 627 ASSERT_EQ(0, fsetpos(fp, &pos4)); 628 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp))); 629 ASSERT_EQ(0, fsetpos(fp, &pos3)); 630 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp))); 631 ASSERT_EQ(0, fsetpos(fp, &pos5)); 632 ASSERT_EQ(WEOF, fgetwc(fp)); 633 634 fclose(fp); 635} 636 637// Exercise the interaction between fpos and seek. 638TEST(stdio, fpos_t_and_seek) { 639 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 640 uselocale(LC_GLOBAL_LOCALE); 641 642 // In glibc-2.16 fseek doesn't work properly in wide mode 643 // (https://sourceware.org/bugzilla/show_bug.cgi?id=14543). One workaround is 644 // to close and re-open the file. We do it in order to make the test pass 645 // with all glibcs. 646 647 TemporaryFile tf; 648 FILE* fp = fdopen(tf.fd, "w+"); 649 ASSERT_TRUE(fp != NULL); 650 651 wchar_t mb_two_bytes = 0x00a2; 652 wchar_t mb_three_bytes = 0x20ac; 653 wchar_t mb_four_bytes = 0x24b62; 654 655 // Write to file. 656 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp))); 657 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp))); 658 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp))); 659 660 fflush(fp); 661 fclose(fp); 662 663 fp = fopen(tf.filename, "r"); 664 ASSERT_TRUE(fp != NULL); 665 666 // Store a valid position. 667 fpos_t mb_two_bytes_pos; 668 ASSERT_EQ(0, fgetpos(fp, &mb_two_bytes_pos)); 669 670 // Move inside mb_four_bytes with fseek. 671 long offset_inside_mb = 6; 672 ASSERT_EQ(0, fseek(fp, offset_inside_mb, SEEK_SET)); 673 674 // Store the "inside multi byte" position. 675 fpos_t pos_inside_mb; 676 ASSERT_EQ(0, fgetpos(fp, &pos_inside_mb)); 677#if defined(__BIONIC__) 678 ASSERT_EQ(offset_inside_mb, static_cast<off_t>(pos_inside_mb)); 679#endif 680 681 // Reading from within a byte should produce an error. 682 ASSERT_EQ(WEOF, fgetwc(fp)); 683 ASSERT_EQ(EILSEQ, errno); 684 685 // Reverting to a valid position should work. 686 ASSERT_EQ(0, fsetpos(fp, &mb_two_bytes_pos)); 687 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp))); 688 689 // Moving withing a multi byte with fsetpos should work but reading should 690 // produce an error. 691 ASSERT_EQ(0, fsetpos(fp, &pos_inside_mb)); 692 ASSERT_EQ(WEOF, fgetwc(fp)); 693 ASSERT_EQ(EILSEQ, errno); 694 695 fclose(fp); 696} 697 698TEST(stdio, fmemopen) { 699 char buf[16]; 700 memset(buf, 0, sizeof(buf)); 701 FILE* fp = fmemopen(buf, sizeof(buf), "r+"); 702 ASSERT_EQ('<', fputc('<', fp)); 703 ASSERT_NE(EOF, fputs("abc>\n", fp)); 704 fflush(fp); 705 706 ASSERT_STREQ("<abc>\n", buf); 707 708 rewind(fp); 709 710 char line[16]; 711 char* s = fgets(line, sizeof(line), fp); 712 ASSERT_TRUE(s != NULL); 713 ASSERT_STREQ("<abc>\n", s); 714 715 fclose(fp); 716} 717 718TEST(stdio, fmemopen_NULL) { 719 FILE* fp = fmemopen(nullptr, 128, "r+"); 720 ASSERT_NE(EOF, fputs("xyz\n", fp)); 721 722 rewind(fp); 723 724 char line[16]; 725 char* s = fgets(line, sizeof(line), fp); 726 ASSERT_TRUE(s != NULL); 727 ASSERT_STREQ("xyz\n", s); 728 729 fclose(fp); 730} 731 732TEST(stdio, fmemopen_EINVAL) { 733 char buf[16]; 734 735 // Invalid size. 736 errno = 0; 737 ASSERT_EQ(nullptr, fmemopen(buf, 0, "r+")); 738 ASSERT_EQ(EINVAL, errno); 739 740 // No '+' with NULL buffer. 741 errno = 0; 742 ASSERT_EQ(nullptr, fmemopen(nullptr, 0, "r")); 743 ASSERT_EQ(EINVAL, errno); 744} 745 746TEST(stdio, open_memstream) { 747 char* p = nullptr; 748 size_t size = 0; 749 FILE* fp = open_memstream(&p, &size); 750 ASSERT_NE(EOF, fputs("hello, world!", fp)); 751 fclose(fp); 752 753 ASSERT_STREQ("hello, world!", p); 754 ASSERT_EQ(strlen("hello, world!"), size); 755 free(p); 756} 757 758TEST(stdio, open_memstream_EINVAL) { 759#if defined(__BIONIC__) 760 char* p; 761 size_t size; 762 763 // Invalid buffer. 764 errno = 0; 765 ASSERT_EQ(nullptr, open_memstream(nullptr, &size)); 766 ASSERT_EQ(EINVAL, errno); 767 768 // Invalid size. 769 errno = 0; 770 ASSERT_EQ(nullptr, open_memstream(&p, nullptr)); 771 ASSERT_EQ(EINVAL, errno); 772#else 773 GTEST_LOG_(INFO) << "This test does nothing.\n"; 774#endif 775} 776 777TEST(stdio, fdopen_CLOEXEC) { 778 int fd = open("/proc/version", O_RDONLY); 779 ASSERT_TRUE(fd != -1); 780 781 // This fd doesn't have O_CLOEXEC... 782 int flags = fcntl(fd, F_GETFD); 783 ASSERT_TRUE(flags != -1); 784 ASSERT_EQ(0, flags & FD_CLOEXEC); 785 786 FILE* fp = fdopen(fd, "re"); 787 ASSERT_TRUE(fp != NULL); 788 789 // ...but the new one does. 790 flags = fcntl(fileno(fp), F_GETFD); 791 ASSERT_TRUE(flags != -1); 792 ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC); 793 794 fclose(fp); 795 close(fd); 796} 797 798TEST(stdio, freopen_CLOEXEC) { 799 FILE* fp = fopen("/proc/version", "r"); 800 ASSERT_TRUE(fp != NULL); 801 802 // This FILE* doesn't have O_CLOEXEC... 803 int flags = fcntl(fileno(fp), F_GETFD); 804 ASSERT_TRUE(flags != -1); 805 ASSERT_EQ(0, flags & FD_CLOEXEC); 806 807 fp = freopen("/proc/version", "re", fp); 808 809 // ...but the new one does. 810 flags = fcntl(fileno(fp), F_GETFD); 811 ASSERT_TRUE(flags != -1); 812 ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC); 813 814 fclose(fp); 815} 816 817// https://code.google.com/p/android/issues/detail?id=81155 818// http://b/18556607 819TEST(stdio, fread_unbuffered_pathological_performance) { 820 FILE* fp = fopen("/dev/zero", "r"); 821 ASSERT_TRUE(fp != NULL); 822 823 // Make this stream unbuffered. 824 setvbuf(fp, 0, _IONBF, 0); 825 826 char buf[65*1024]; 827 memset(buf, 0xff, sizeof(buf)); 828 829 time_t t0 = time(NULL); 830 for (size_t i = 0; i < 1024; ++i) { 831 fread(buf, 64*1024, 1, fp); 832 } 833 time_t t1 = time(NULL); 834 835 fclose(fp); 836 837 // 1024 64KiB reads should have been very quick. 838 ASSERT_LE(t1 - t0, 1); 839 840 for (size_t i = 0; i < 64*1024; ++i) { 841 ASSERT_EQ('\0', buf[i]); 842 } 843 for (size_t i = 64*1024; i < 65*1024; ++i) { 844 ASSERT_EQ('\xff', buf[i]); 845 } 846} 847