stdio_test.cpp revision e4fa6e9cc7f894a5a85ca50249b1f6e9efd49d3a
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 <vector> 31 32#include "TemporaryFile.h" 33 34#if defined(NOFORTIFY) 35#define STDIO_TEST stdio_nofortify 36#else 37#define STDIO_TEST stdio 38#endif 39 40TEST(STDIO_TEST, flockfile_18208568_stderr) { 41 // Check that we have a _recursive_ mutex for flockfile. 42 flockfile(stderr); 43 feof(stderr); // We don't care about the result, but this needs to take the lock. 44 funlockfile(stderr); 45} 46 47TEST(STDIO_TEST, flockfile_18208568_regular) { 48 // We never had a bug for streams other than stdin/stdout/stderr, but test anyway. 49 FILE* fp = fopen("/dev/null", "w"); 50 ASSERT_TRUE(fp != NULL); 51 flockfile(fp); 52 feof(fp); 53 funlockfile(fp); 54 fclose(fp); 55} 56 57TEST(STDIO_TEST, tmpfile_fileno_fprintf_rewind_fgets) { 58 FILE* fp = tmpfile(); 59 ASSERT_TRUE(fp != NULL); 60 61 int fd = fileno(fp); 62 ASSERT_NE(fd, -1); 63 64 struct stat sb; 65 int rc = fstat(fd, &sb); 66 ASSERT_NE(rc, -1); 67 ASSERT_EQ(sb.st_mode & 0777, 0600U); 68 69 rc = fprintf(fp, "hello\n"); 70 ASSERT_EQ(rc, 6); 71 72 rewind(fp); 73 74 char buf[16]; 75 char* s = fgets(buf, sizeof(buf), fp); 76 ASSERT_TRUE(s != NULL); 77 ASSERT_STREQ("hello\n", s); 78 79 fclose(fp); 80} 81 82TEST(STDIO_TEST, dprintf) { 83 TemporaryFile tf; 84 85 int rc = dprintf(tf.fd, "hello\n"); 86 ASSERT_EQ(rc, 6); 87 88 lseek(tf.fd, 0, SEEK_SET); 89 FILE* tfile = fdopen(tf.fd, "r"); 90 ASSERT_TRUE(tfile != NULL); 91 92 char buf[7]; 93 ASSERT_EQ(buf, fgets(buf, sizeof(buf), tfile)); 94 ASSERT_STREQ("hello\n", buf); 95 // Make sure there isn't anything else in the file. 96 ASSERT_EQ(NULL, fgets(buf, sizeof(buf), tfile)); 97 fclose(tfile); 98} 99 100TEST(STDIO_TEST, getdelim) { 101 FILE* fp = tmpfile(); 102 ASSERT_TRUE(fp != NULL); 103 104 const char* line_written = "This is a test"; 105 int rc = fprintf(fp, "%s", line_written); 106 ASSERT_EQ(rc, static_cast<int>(strlen(line_written))); 107 108 rewind(fp); 109 110 char* word_read = NULL; 111 size_t allocated_length = 0; 112 113 const char* expected[] = { "This ", " ", "is ", "a ", "test" }; 114 for (size_t i = 0; i < 5; ++i) { 115 ASSERT_FALSE(feof(fp)); 116 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), static_cast<int>(strlen(expected[i]))); 117 ASSERT_GE(allocated_length, strlen(expected[i])); 118 ASSERT_STREQ(expected[i], word_read); 119 } 120 // The last read should have set the end-of-file indicator for the stream. 121 ASSERT_TRUE(feof(fp)); 122 clearerr(fp); 123 124 // getdelim returns -1 but doesn't set errno if we're already at EOF. 125 // It should set the end-of-file indicator for the stream, though. 126 errno = 0; 127 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), -1); 128 ASSERT_EQ(0, errno); 129 ASSERT_TRUE(feof(fp)); 130 131 free(word_read); 132 fclose(fp); 133} 134 135TEST(STDIO_TEST, getdelim_invalid) { 136 FILE* fp = tmpfile(); 137 ASSERT_TRUE(fp != NULL); 138 139 char* buffer = NULL; 140 size_t buffer_length = 0; 141 142 // The first argument can't be NULL. 143 errno = 0; 144 ASSERT_EQ(getdelim(NULL, &buffer_length, ' ', fp), -1); 145 ASSERT_EQ(EINVAL, errno); 146 147 // The second argument can't be NULL. 148 errno = 0; 149 ASSERT_EQ(getdelim(&buffer, NULL, ' ', fp), -1); 150 ASSERT_EQ(EINVAL, errno); 151 152 // The underlying fd can't be closed. 153 ASSERT_EQ(0, close(fileno(fp))); 154 errno = 0; 155 ASSERT_EQ(getdelim(&buffer, &buffer_length, ' ', fp), -1); 156 ASSERT_EQ(EBADF, errno); 157 fclose(fp); 158} 159 160TEST(STDIO_TEST, getdelim_directory) { 161 FILE* fp = fopen("/proc", "r"); 162 ASSERT_TRUE(fp != NULL); 163 char* word_read; 164 size_t allocated_length; 165 ASSERT_EQ(-1, getdelim(&word_read, &allocated_length, ' ', fp)); 166 fclose(fp); 167} 168 169TEST(STDIO_TEST, getline) { 170 FILE* fp = tmpfile(); 171 ASSERT_TRUE(fp != NULL); 172 173 const char* line_written = "This is a test for getline\n"; 174 const size_t line_count = 5; 175 176 for (size_t i = 0; i < line_count; ++i) { 177 int rc = fprintf(fp, "%s", line_written); 178 ASSERT_EQ(rc, static_cast<int>(strlen(line_written))); 179 } 180 181 rewind(fp); 182 183 char* line_read = NULL; 184 size_t allocated_length = 0; 185 186 size_t read_line_count = 0; 187 ssize_t read_char_count; 188 while ((read_char_count = getline(&line_read, &allocated_length, fp)) != -1) { 189 ASSERT_EQ(read_char_count, static_cast<int>(strlen(line_written))); 190 ASSERT_GE(allocated_length, strlen(line_written)); 191 ASSERT_STREQ(line_written, line_read); 192 ++read_line_count; 193 } 194 ASSERT_EQ(read_line_count, line_count); 195 196 // The last read should have set the end-of-file indicator for the stream. 197 ASSERT_TRUE(feof(fp)); 198 clearerr(fp); 199 200 // getline returns -1 but doesn't set errno if we're already at EOF. 201 // It should set the end-of-file indicator for the stream, though. 202 errno = 0; 203 ASSERT_EQ(getline(&line_read, &allocated_length, fp), -1); 204 ASSERT_EQ(0, errno); 205 ASSERT_TRUE(feof(fp)); 206 207 free(line_read); 208 fclose(fp); 209} 210 211TEST(STDIO_TEST, getline_invalid) { 212 FILE* fp = tmpfile(); 213 ASSERT_TRUE(fp != NULL); 214 215 char* buffer = NULL; 216 size_t buffer_length = 0; 217 218 // The first argument can't be NULL. 219 errno = 0; 220 ASSERT_EQ(getline(NULL, &buffer_length, fp), -1); 221 ASSERT_EQ(EINVAL, errno); 222 223 // The second argument can't be NULL. 224 errno = 0; 225 ASSERT_EQ(getline(&buffer, NULL, fp), -1); 226 ASSERT_EQ(EINVAL, errno); 227 228 // The underlying fd can't be closed. 229 ASSERT_EQ(0, close(fileno(fp))); 230 errno = 0; 231 ASSERT_EQ(getline(&buffer, &buffer_length, fp), -1); 232 ASSERT_EQ(EBADF, errno); 233 fclose(fp); 234} 235 236TEST(STDIO_TEST, printf_ssize_t) { 237 // http://b/8253769 238 ASSERT_EQ(sizeof(ssize_t), sizeof(long int)); 239 ASSERT_EQ(sizeof(ssize_t), sizeof(size_t)); 240 // For our 32-bit ABI, we had a ssize_t definition that confuses GCC into saying: 241 // error: format '%zd' expects argument of type 'signed size_t', 242 // but argument 4 has type 'ssize_t {aka long int}' [-Werror=format] 243 ssize_t v = 1; 244 char buf[32]; 245 snprintf(buf, sizeof(buf), "%zd", v); 246} 247 248// https://code.google.com/p/android/issues/detail?id=64886 249TEST(STDIO_TEST, snprintf_a) { 250 char buf[BUFSIZ]; 251 EXPECT_EQ(23, snprintf(buf, sizeof(buf), "<%a>", 9990.235)); 252 EXPECT_STREQ("<0x1.3831e147ae148p+13>", buf); 253} 254 255TEST(STDIO_TEST, snprintf_lc) { 256 char buf[BUFSIZ]; 257 wint_t wc = L'a'; 258 EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%lc>", wc)); 259 EXPECT_STREQ("<a>", buf); 260} 261 262TEST(STDIO_TEST, snprintf_ls) { 263 char buf[BUFSIZ]; 264 wchar_t* ws = NULL; 265 EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%ls>", ws)); 266 EXPECT_STREQ("<(null)>", buf); 267 268 wchar_t chars[] = { L'h', L'i', 0 }; 269 ws = chars; 270 EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%ls>", ws)); 271 EXPECT_STREQ("<hi>", buf); 272} 273 274TEST(STDIO_TEST, snprintf_n) { 275#if defined(__BIONIC__) 276 // http://b/14492135 277 char buf[32]; 278 int i = 1234; 279 EXPECT_EQ(5, snprintf(buf, sizeof(buf), "a %n b", &i)); 280 EXPECT_EQ(1234, i); 281 EXPECT_STREQ("a n b", buf); 282#else 283 GTEST_LOG_(INFO) << "This test does nothing on glibc.\n"; 284#endif 285} 286 287TEST(STDIO_TEST, snprintf_smoke) { 288 char buf[BUFSIZ]; 289 290 snprintf(buf, sizeof(buf), "a"); 291 EXPECT_STREQ("a", buf); 292 293 snprintf(buf, sizeof(buf), "%%"); 294 EXPECT_STREQ("%", buf); 295 296 snprintf(buf, sizeof(buf), "01234"); 297 EXPECT_STREQ("01234", buf); 298 299 snprintf(buf, sizeof(buf), "a%sb", "01234"); 300 EXPECT_STREQ("a01234b", buf); 301 302 char* s = NULL; 303 snprintf(buf, sizeof(buf), "a%sb", s); 304 EXPECT_STREQ("a(null)b", buf); 305 306 snprintf(buf, sizeof(buf), "aa%scc", "bb"); 307 EXPECT_STREQ("aabbcc", buf); 308 309 snprintf(buf, sizeof(buf), "a%cc", 'b'); 310 EXPECT_STREQ("abc", buf); 311 312 snprintf(buf, sizeof(buf), "a%db", 1234); 313 EXPECT_STREQ("a1234b", buf); 314 315 snprintf(buf, sizeof(buf), "a%db", -8123); 316 EXPECT_STREQ("a-8123b", buf); 317 318 snprintf(buf, sizeof(buf), "a%hdb", static_cast<short>(0x7fff0010)); 319 EXPECT_STREQ("a16b", buf); 320 321 snprintf(buf, sizeof(buf), "a%hhdb", static_cast<char>(0x7fffff10)); 322 EXPECT_STREQ("a16b", buf); 323 324 snprintf(buf, sizeof(buf), "a%lldb", 0x1000000000LL); 325 EXPECT_STREQ("a68719476736b", buf); 326 327 snprintf(buf, sizeof(buf), "a%ldb", 70000L); 328 EXPECT_STREQ("a70000b", buf); 329 330 snprintf(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234)); 331 EXPECT_STREQ("a0xb0001234b", buf); 332 333 snprintf(buf, sizeof(buf), "a%xz", 0x12ab); 334 EXPECT_STREQ("a12abz", buf); 335 336 snprintf(buf, sizeof(buf), "a%Xz", 0x12ab); 337 EXPECT_STREQ("a12ABz", buf); 338 339 snprintf(buf, sizeof(buf), "a%08xz", 0x123456); 340 EXPECT_STREQ("a00123456z", buf); 341 342 snprintf(buf, sizeof(buf), "a%5dz", 1234); 343 EXPECT_STREQ("a 1234z", buf); 344 345 snprintf(buf, sizeof(buf), "a%05dz", 1234); 346 EXPECT_STREQ("a01234z", buf); 347 348 snprintf(buf, sizeof(buf), "a%8dz", 1234); 349 EXPECT_STREQ("a 1234z", buf); 350 351 snprintf(buf, sizeof(buf), "a%-8dz", 1234); 352 EXPECT_STREQ("a1234 z", buf); 353 354 snprintf(buf, sizeof(buf), "A%-11sZ", "abcdef"); 355 EXPECT_STREQ("Aabcdef Z", buf); 356 357 snprintf(buf, sizeof(buf), "A%s:%dZ", "hello", 1234); 358 EXPECT_STREQ("Ahello:1234Z", buf); 359 360 snprintf(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5); 361 EXPECT_STREQ("a005:5:05z", buf); 362 363 void* p = NULL; 364 snprintf(buf, sizeof(buf), "a%d,%pz", 5, p); 365#if defined(__BIONIC__) 366 EXPECT_STREQ("a5,0x0z", buf); 367#else // __BIONIC__ 368 EXPECT_STREQ("a5,(nil)z", buf); 369#endif // __BIONIC__ 370 371 snprintf(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8); 372 EXPECT_STREQ("a68719476736,6,7,8z", buf); 373 374 snprintf(buf, sizeof(buf), "a_%f_b", 1.23f); 375 EXPECT_STREQ("a_1.230000_b", buf); 376 377 snprintf(buf, sizeof(buf), "a_%g_b", 3.14); 378 EXPECT_STREQ("a_3.14_b", buf); 379 380 snprintf(buf, sizeof(buf), "%1$s %1$s", "print_me_twice"); 381 EXPECT_STREQ("print_me_twice print_me_twice", buf); 382} 383 384template <typename T> 385void CheckInfNan(int snprintf_fn(T*, size_t, const T*, ...), 386 const T* fmt, const T* fmt_plus, 387 const T* minus_inf, const T* inf_, const T* plus_inf, 388 const T* minus_nan, const T* nan_, const T* plus_nan) { 389 T buf[BUFSIZ]; 390 391 snprintf_fn(buf, sizeof(buf), fmt, nan("")); 392 EXPECT_STREQ(nan_, buf) << fmt; 393 snprintf_fn(buf, sizeof(buf), fmt, -nan("")); 394 EXPECT_STREQ(minus_nan, buf) << fmt; 395 snprintf_fn(buf, sizeof(buf), fmt_plus, nan("")); 396 EXPECT_STREQ(plus_nan, buf) << fmt_plus; 397 snprintf_fn(buf, sizeof(buf), fmt_plus, -nan("")); 398 EXPECT_STREQ(minus_nan, buf) << fmt_plus; 399 400 snprintf_fn(buf, sizeof(buf), fmt, HUGE_VAL); 401 EXPECT_STREQ(inf_, buf) << fmt; 402 snprintf_fn(buf, sizeof(buf), fmt, -HUGE_VAL); 403 EXPECT_STREQ(minus_inf, buf) << fmt; 404 snprintf_fn(buf, sizeof(buf), fmt_plus, HUGE_VAL); 405 EXPECT_STREQ(plus_inf, buf) << fmt_plus; 406 snprintf_fn(buf, sizeof(buf), fmt_plus, -HUGE_VAL); 407 EXPECT_STREQ(minus_inf, buf) << fmt_plus; 408} 409 410TEST(STDIO_TEST, snprintf_inf_nan) { 411 CheckInfNan(snprintf, "%a", "%+a", "-inf", "inf", "+inf", "-nan", "nan", "+nan"); 412 CheckInfNan(snprintf, "%A", "%+A", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN"); 413 CheckInfNan(snprintf, "%e", "%+e", "-inf", "inf", "+inf", "-nan", "nan", "+nan"); 414 CheckInfNan(snprintf, "%E", "%+E", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN"); 415 CheckInfNan(snprintf, "%f", "%+f", "-inf", "inf", "+inf", "-nan", "nan", "+nan"); 416 CheckInfNan(snprintf, "%F", "%+F", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN"); 417 CheckInfNan(snprintf, "%g", "%+g", "-inf", "inf", "+inf", "-nan", "nan", "+nan"); 418 CheckInfNan(snprintf, "%G", "%+G", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN"); 419} 420 421TEST(STDIO_TEST, wsprintf_inf_nan) { 422 CheckInfNan(swprintf, L"%a", L"%+a", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan"); 423 CheckInfNan(swprintf, L"%A", L"%+A", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN"); 424 CheckInfNan(swprintf, L"%e", L"%+e", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan"); 425 CheckInfNan(swprintf, L"%E", L"%+E", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN"); 426 CheckInfNan(swprintf, L"%f", L"%+f", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan"); 427 CheckInfNan(swprintf, L"%F", L"%+F", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN"); 428 CheckInfNan(swprintf, L"%g", L"%+g", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan"); 429 CheckInfNan(swprintf, L"%G", L"%+G", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN"); 430} 431 432TEST(STDIO_TEST, snprintf_d_INT_MAX) { 433 char buf[BUFSIZ]; 434 snprintf(buf, sizeof(buf), "%d", INT_MAX); 435 EXPECT_STREQ("2147483647", buf); 436} 437 438TEST(STDIO_TEST, snprintf_d_INT_MIN) { 439 char buf[BUFSIZ]; 440 snprintf(buf, sizeof(buf), "%d", INT_MIN); 441 EXPECT_STREQ("-2147483648", buf); 442} 443 444TEST(STDIO_TEST, snprintf_ld_LONG_MAX) { 445 char buf[BUFSIZ]; 446 snprintf(buf, sizeof(buf), "%ld", LONG_MAX); 447#if __LP64__ 448 EXPECT_STREQ("9223372036854775807", buf); 449#else 450 EXPECT_STREQ("2147483647", buf); 451#endif 452} 453 454TEST(STDIO_TEST, snprintf_ld_LONG_MIN) { 455 char buf[BUFSIZ]; 456 snprintf(buf, sizeof(buf), "%ld", LONG_MIN); 457#if __LP64__ 458 EXPECT_STREQ("-9223372036854775808", buf); 459#else 460 EXPECT_STREQ("-2147483648", buf); 461#endif 462} 463 464TEST(STDIO_TEST, snprintf_lld_LLONG_MAX) { 465 char buf[BUFSIZ]; 466 snprintf(buf, sizeof(buf), "%lld", LLONG_MAX); 467 EXPECT_STREQ("9223372036854775807", buf); 468} 469 470TEST(STDIO_TEST, snprintf_lld_LLONG_MIN) { 471 char buf[BUFSIZ]; 472 snprintf(buf, sizeof(buf), "%lld", LLONG_MIN); 473 EXPECT_STREQ("-9223372036854775808", buf); 474} 475 476TEST(STDIO_TEST, snprintf_e) { 477 char buf[BUFSIZ]; 478 479 snprintf(buf, sizeof(buf), "%e", 1.5); 480 EXPECT_STREQ("1.500000e+00", buf); 481 482 snprintf(buf, sizeof(buf), "%Le", 1.5l); 483 EXPECT_STREQ("1.500000e+00", buf); 484} 485 486TEST(STDIO_TEST, snprintf_negative_zero_5084292) { 487 char buf[BUFSIZ]; 488 489 snprintf(buf, sizeof(buf), "%e", -0.0); 490 EXPECT_STREQ("-0.000000e+00", buf); 491 snprintf(buf, sizeof(buf), "%E", -0.0); 492 EXPECT_STREQ("-0.000000E+00", buf); 493 snprintf(buf, sizeof(buf), "%f", -0.0); 494 EXPECT_STREQ("-0.000000", buf); 495 snprintf(buf, sizeof(buf), "%F", -0.0); 496 EXPECT_STREQ("-0.000000", buf); 497 snprintf(buf, sizeof(buf), "%g", -0.0); 498 EXPECT_STREQ("-0", buf); 499 snprintf(buf, sizeof(buf), "%G", -0.0); 500 EXPECT_STREQ("-0", buf); 501 snprintf(buf, sizeof(buf), "%a", -0.0); 502 EXPECT_STREQ("-0x0p+0", buf); 503 snprintf(buf, sizeof(buf), "%A", -0.0); 504 EXPECT_STREQ("-0X0P+0", buf); 505} 506 507TEST(STDIO_TEST, snprintf_utf8_15439554) { 508 locale_t cloc = newlocale(LC_ALL, "C.UTF-8", 0); 509 locale_t old_locale = uselocale(cloc); 510 511 // http://b/15439554 512 char buf[BUFSIZ]; 513 514 // 1-byte character. 515 snprintf(buf, sizeof(buf), "%dx%d", 1, 2); 516 EXPECT_STREQ("1x2", buf); 517 // 2-byte character. 518 snprintf(buf, sizeof(buf), "%d\xc2\xa2%d", 1, 2); 519 EXPECT_STREQ("1¢2", buf); 520 // 3-byte character. 521 snprintf(buf, sizeof(buf), "%d\xe2\x82\xac%d", 1, 2); 522 EXPECT_STREQ("1€2", buf); 523 // 4-byte character. 524 snprintf(buf, sizeof(buf), "%d\xf0\xa4\xad\xa2%d", 1, 2); 525 EXPECT_STREQ("12", buf); 526 527 uselocale(old_locale); 528 freelocale(cloc); 529} 530 531TEST(STDIO_TEST, fprintf_failures_7229520) { 532 // http://b/7229520 533 FILE* fp; 534 535 // Unbuffered case where the fprintf(3) itself fails. 536 ASSERT_NE(nullptr, fp = tmpfile()); 537 setbuf(fp, NULL); 538 ASSERT_EQ(4, fprintf(fp, "epic")); 539 ASSERT_EQ(0, close(fileno(fp))); 540 ASSERT_EQ(-1, fprintf(fp, "fail")); 541 ASSERT_EQ(-1, fclose(fp)); 542 543 // Buffered case where we won't notice until the fclose(3). 544 // It's likely this is what was actually seen in http://b/7229520, 545 // and that expecting fprintf to fail is setting yourself up for 546 // disappointment. Remember to check fclose(3)'s return value, kids! 547 ASSERT_NE(nullptr, fp = tmpfile()); 548 ASSERT_EQ(4, fprintf(fp, "epic")); 549 ASSERT_EQ(0, close(fileno(fp))); 550 ASSERT_EQ(4, fprintf(fp, "fail")); 551 ASSERT_EQ(-1, fclose(fp)); 552} 553 554TEST(STDIO_TEST, popen) { 555 FILE* fp = popen("cat /proc/version", "r"); 556 ASSERT_TRUE(fp != NULL); 557 558 char buf[16]; 559 char* s = fgets(buf, sizeof(buf), fp); 560 buf[13] = '\0'; 561 ASSERT_STREQ("Linux version", s); 562 563 ASSERT_EQ(0, pclose(fp)); 564} 565 566TEST(STDIO_TEST, getc) { 567 FILE* fp = fopen("/proc/version", "r"); 568 ASSERT_TRUE(fp != NULL); 569 ASSERT_EQ('L', getc(fp)); 570 ASSERT_EQ('i', getc(fp)); 571 ASSERT_EQ('n', getc(fp)); 572 ASSERT_EQ('u', getc(fp)); 573 ASSERT_EQ('x', getc(fp)); 574 fclose(fp); 575} 576 577TEST(STDIO_TEST, putc) { 578 FILE* fp = fopen("/proc/version", "r"); 579 ASSERT_TRUE(fp != NULL); 580 ASSERT_EQ(EOF, putc('x', fp)); 581 fclose(fp); 582} 583 584TEST(STDIO_TEST, sscanf) { 585 char s1[123]; 586 int i1; 587 double d1; 588 char s2[123]; 589 ASSERT_EQ(3, sscanf(" hello 123 1.23 ", "%s %i %lf %s", s1, &i1, &d1, s2)); 590 ASSERT_STREQ("hello", s1); 591 ASSERT_EQ(123, i1); 592 ASSERT_DOUBLE_EQ(1.23, d1); 593} 594 595TEST(STDIO_TEST, cantwrite_EBADF) { 596 // If we open a file read-only... 597 FILE* fp = fopen("/proc/version", "r"); 598 599 // ...all attempts to write to that file should return failure. 600 601 // They should also set errno to EBADF. This isn't POSIX, but it's traditional. 602 // glibc gets the wide-character functions wrong. 603 604 errno = 0; 605 EXPECT_EQ(EOF, putc('x', fp)); 606 EXPECT_EQ(EBADF, errno); 607 608 errno = 0; 609 EXPECT_EQ(EOF, fprintf(fp, "hello")); 610 EXPECT_EQ(EBADF, errno); 611 612 errno = 0; 613 EXPECT_EQ(EOF, fwprintf(fp, L"hello")); 614#if defined(__BIONIC__) 615 EXPECT_EQ(EBADF, errno); 616#endif 617 618 errno = 0; 619 EXPECT_EQ(0U, fwrite("hello", 1, 2, fp)); 620 EXPECT_EQ(EBADF, errno); 621 622 errno = 0; 623 EXPECT_EQ(EOF, fputs("hello", fp)); 624 EXPECT_EQ(EBADF, errno); 625 626 errno = 0; 627 EXPECT_EQ(WEOF, fputwc(L'x', fp)); 628#if defined(__BIONIC__) 629 EXPECT_EQ(EBADF, errno); 630#endif 631} 632 633// Tests that we can only have a consistent and correct fpos_t when using 634// f*pos functions (i.e. fpos doesn't get inside a multi byte character). 635TEST(STDIO_TEST, consistent_fpos_t) { 636 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 637 uselocale(LC_GLOBAL_LOCALE); 638 639 FILE* fp = tmpfile(); 640 ASSERT_TRUE(fp != NULL); 641 642 wchar_t mb_one_bytes = L'h'; 643 wchar_t mb_two_bytes = 0x00a2; 644 wchar_t mb_three_bytes = 0x20ac; 645 wchar_t mb_four_bytes = 0x24b62; 646 647 // Write to file. 648 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fputwc(mb_one_bytes, fp))); 649 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp))); 650 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp))); 651 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp))); 652 653 rewind(fp); 654 655 // Record each character position. 656 fpos_t pos1; 657 fpos_t pos2; 658 fpos_t pos3; 659 fpos_t pos4; 660 fpos_t pos5; 661 EXPECT_EQ(0, fgetpos(fp, &pos1)); 662 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp))); 663 EXPECT_EQ(0, fgetpos(fp, &pos2)); 664 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp))); 665 EXPECT_EQ(0, fgetpos(fp, &pos3)); 666 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp))); 667 EXPECT_EQ(0, fgetpos(fp, &pos4)); 668 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp))); 669 EXPECT_EQ(0, fgetpos(fp, &pos5)); 670 671#if defined(__BIONIC__) 672 // Bionic's fpos_t is just an alias for off_t. This is inherited from OpenBSD 673 // upstream. Glibc differs by storing the mbstate_t inside its fpos_t. In 674 // Bionic (and upstream OpenBSD) the mbstate_t is stored inside the FILE 675 // structure. 676 ASSERT_EQ(0, static_cast<off_t>(pos1)); 677 ASSERT_EQ(1, static_cast<off_t>(pos2)); 678 ASSERT_EQ(3, static_cast<off_t>(pos3)); 679 ASSERT_EQ(6, static_cast<off_t>(pos4)); 680 ASSERT_EQ(10, static_cast<off_t>(pos5)); 681#endif 682 683 // Exercise back and forth movements of the position. 684 ASSERT_EQ(0, fsetpos(fp, &pos2)); 685 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp))); 686 ASSERT_EQ(0, fsetpos(fp, &pos1)); 687 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp))); 688 ASSERT_EQ(0, fsetpos(fp, &pos4)); 689 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp))); 690 ASSERT_EQ(0, fsetpos(fp, &pos3)); 691 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp))); 692 ASSERT_EQ(0, fsetpos(fp, &pos5)); 693 ASSERT_EQ(WEOF, fgetwc(fp)); 694 695 fclose(fp); 696} 697 698// Exercise the interaction between fpos and seek. 699TEST(STDIO_TEST, fpos_t_and_seek) { 700 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 701 uselocale(LC_GLOBAL_LOCALE); 702 703 // In glibc-2.16 fseek doesn't work properly in wide mode 704 // (https://sourceware.org/bugzilla/show_bug.cgi?id=14543). One workaround is 705 // to close and re-open the file. We do it in order to make the test pass 706 // with all glibcs. 707 708 TemporaryFile tf; 709 FILE* fp = fdopen(tf.fd, "w+"); 710 ASSERT_TRUE(fp != NULL); 711 712 wchar_t mb_two_bytes = 0x00a2; 713 wchar_t mb_three_bytes = 0x20ac; 714 wchar_t mb_four_bytes = 0x24b62; 715 716 // Write to file. 717 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp))); 718 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp))); 719 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp))); 720 721 fflush(fp); 722 fclose(fp); 723 724 fp = fopen(tf.filename, "r"); 725 ASSERT_TRUE(fp != NULL); 726 727 // Store a valid position. 728 fpos_t mb_two_bytes_pos; 729 ASSERT_EQ(0, fgetpos(fp, &mb_two_bytes_pos)); 730 731 // Move inside mb_four_bytes with fseek. 732 long offset_inside_mb = 6; 733 ASSERT_EQ(0, fseek(fp, offset_inside_mb, SEEK_SET)); 734 735 // Store the "inside multi byte" position. 736 fpos_t pos_inside_mb; 737 ASSERT_EQ(0, fgetpos(fp, &pos_inside_mb)); 738#if defined(__BIONIC__) 739 ASSERT_EQ(offset_inside_mb, static_cast<off_t>(pos_inside_mb)); 740#endif 741 742 // Reading from within a byte should produce an error. 743 ASSERT_EQ(WEOF, fgetwc(fp)); 744 ASSERT_EQ(EILSEQ, errno); 745 746 // Reverting to a valid position should work. 747 ASSERT_EQ(0, fsetpos(fp, &mb_two_bytes_pos)); 748 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp))); 749 750 // Moving withing a multi byte with fsetpos should work but reading should 751 // produce an error. 752 ASSERT_EQ(0, fsetpos(fp, &pos_inside_mb)); 753 ASSERT_EQ(WEOF, fgetwc(fp)); 754 ASSERT_EQ(EILSEQ, errno); 755 756 fclose(fp); 757} 758 759TEST(STDIO_TEST, fmemopen) { 760 char buf[16]; 761 memset(buf, 0, sizeof(buf)); 762 FILE* fp = fmemopen(buf, sizeof(buf), "r+"); 763 ASSERT_EQ('<', fputc('<', fp)); 764 ASSERT_NE(EOF, fputs("abc>\n", fp)); 765 fflush(fp); 766 767 ASSERT_STREQ("<abc>\n", buf); 768 769 rewind(fp); 770 771 char line[16]; 772 char* s = fgets(line, sizeof(line), fp); 773 ASSERT_TRUE(s != NULL); 774 ASSERT_STREQ("<abc>\n", s); 775 776 fclose(fp); 777} 778 779TEST(STDIO_TEST, fmemopen_NULL) { 780 FILE* fp = fmemopen(nullptr, 128, "r+"); 781 ASSERT_NE(EOF, fputs("xyz\n", fp)); 782 783 rewind(fp); 784 785 char line[16]; 786 char* s = fgets(line, sizeof(line), fp); 787 ASSERT_TRUE(s != NULL); 788 ASSERT_STREQ("xyz\n", s); 789 790 fclose(fp); 791} 792 793TEST(STDIO_TEST, fmemopen_EINVAL) { 794 char buf[16]; 795 796 // Invalid size. 797 errno = 0; 798 ASSERT_EQ(nullptr, fmemopen(buf, 0, "r+")); 799 ASSERT_EQ(EINVAL, errno); 800 801 // No '+' with NULL buffer. 802 errno = 0; 803 ASSERT_EQ(nullptr, fmemopen(nullptr, 0, "r")); 804 ASSERT_EQ(EINVAL, errno); 805} 806 807TEST(STDIO_TEST, open_memstream) { 808 char* p = nullptr; 809 size_t size = 0; 810 FILE* fp = open_memstream(&p, &size); 811 ASSERT_NE(EOF, fputs("hello, world!", fp)); 812 fclose(fp); 813 814 ASSERT_STREQ("hello, world!", p); 815 ASSERT_EQ(strlen("hello, world!"), size); 816 free(p); 817} 818 819TEST(STDIO_TEST, open_memstream_EINVAL) { 820#if defined(__BIONIC__) 821 char* p; 822 size_t size; 823 824 // Invalid buffer. 825 errno = 0; 826 ASSERT_EQ(nullptr, open_memstream(nullptr, &size)); 827 ASSERT_EQ(EINVAL, errno); 828 829 // Invalid size. 830 errno = 0; 831 ASSERT_EQ(nullptr, open_memstream(&p, nullptr)); 832 ASSERT_EQ(EINVAL, errno); 833#else 834 GTEST_LOG_(INFO) << "This test does nothing on glibc.\n"; 835#endif 836} 837 838TEST(STDIO_TEST, fdopen_CLOEXEC) { 839 int fd = open("/proc/version", O_RDONLY); 840 ASSERT_TRUE(fd != -1); 841 842 // This fd doesn't have O_CLOEXEC... 843 int flags = fcntl(fd, F_GETFD); 844 ASSERT_TRUE(flags != -1); 845 ASSERT_EQ(0, flags & FD_CLOEXEC); 846 847 FILE* fp = fdopen(fd, "re"); 848 ASSERT_TRUE(fp != NULL); 849 850 // ...but the new one does. 851 flags = fcntl(fileno(fp), F_GETFD); 852 ASSERT_TRUE(flags != -1); 853 ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC); 854 855 fclose(fp); 856 close(fd); 857} 858 859TEST(STDIO_TEST, freopen_CLOEXEC) { 860 FILE* fp = fopen("/proc/version", "r"); 861 ASSERT_TRUE(fp != NULL); 862 863 // This FILE* doesn't have O_CLOEXEC... 864 int flags = fcntl(fileno(fp), F_GETFD); 865 ASSERT_TRUE(flags != -1); 866 ASSERT_EQ(0, flags & FD_CLOEXEC); 867 868 fp = freopen("/proc/version", "re", fp); 869 870 // ...but the new one does. 871 flags = fcntl(fileno(fp), F_GETFD); 872 ASSERT_TRUE(flags != -1); 873 ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC); 874 875 fclose(fp); 876} 877 878// https://code.google.com/p/android/issues/detail?id=81155 879// http://b/18556607 880TEST(STDIO_TEST, fread_unbuffered_pathological_performance) { 881 FILE* fp = fopen("/dev/zero", "r"); 882 ASSERT_TRUE(fp != NULL); 883 884 // Make this stream unbuffered. 885 setvbuf(fp, 0, _IONBF, 0); 886 887 char buf[65*1024]; 888 memset(buf, 0xff, sizeof(buf)); 889 890 time_t t0 = time(NULL); 891 for (size_t i = 0; i < 1024; ++i) { 892 ASSERT_EQ(1U, fread(buf, 64*1024, 1, fp)); 893 } 894 time_t t1 = time(NULL); 895 896 fclose(fp); 897 898 // 1024 64KiB reads should have been very quick. 899 ASSERT_LE(t1 - t0, 1); 900 901 for (size_t i = 0; i < 64*1024; ++i) { 902 ASSERT_EQ('\0', buf[i]); 903 } 904 for (size_t i = 64*1024; i < 65*1024; ++i) { 905 ASSERT_EQ('\xff', buf[i]); 906 } 907} 908 909TEST(STDIO_TEST, fread_EOF) { 910 std::string digits("0123456789"); 911 FILE* fp = fmemopen(&digits[0], digits.size(), "r"); 912 913 // Try to read too much, but little enough that it still fits in the FILE's internal buffer. 914 char buf1[4 * 4]; 915 memset(buf1, 0, sizeof(buf1)); 916 ASSERT_EQ(2U, fread(buf1, 4, 4, fp)); 917 ASSERT_STREQ("0123456789", buf1); 918 ASSERT_TRUE(feof(fp)); 919 920 rewind(fp); 921 922 // Try to read way too much so stdio tries to read more direct from the stream. 923 char buf2[4 * 4096]; 924 memset(buf2, 0, sizeof(buf2)); 925 ASSERT_EQ(2U, fread(buf2, 4, 4096, fp)); 926 ASSERT_STREQ("0123456789", buf2); 927 ASSERT_TRUE(feof(fp)); 928 929 fclose(fp); 930} 931 932static void test_fread_from_write_only_stream(size_t n) { 933 FILE* fp = fopen("/dev/null", "w"); 934 std::vector<char> buf(n, 0); 935 errno = 0; 936 ASSERT_EQ(0U, fread(&buf[0], n, 1, fp)); 937 ASSERT_EQ(EBADF, errno); 938 ASSERT_TRUE(ferror(fp)); 939 ASSERT_FALSE(feof(fp)); 940 fclose(fp); 941} 942 943TEST(STDIO_TEST, fread_from_write_only_stream_slow_path) { 944 test_fread_from_write_only_stream(1); 945} 946 947TEST(STDIO_TEST, fread_from_write_only_stream_fast_path) { 948 test_fread_from_write_only_stream(64*1024); 949} 950 951static void test_fwrite_after_fread(size_t n) { 952 TemporaryFile tf; 953 954 FILE* fp = fdopen(tf.fd, "w+"); 955 ASSERT_EQ(1U, fwrite("1", 1, 1, fp)); 956 fflush(fp); 957 958 // We've flushed but not rewound, so there's nothing to read. 959 std::vector<char> buf(n, 0); 960 ASSERT_EQ(0U, fread(&buf[0], 1, buf.size(), fp)); 961 ASSERT_TRUE(feof(fp)); 962 963 // But hitting EOF doesn't prevent us from writing... 964 errno = 0; 965 ASSERT_EQ(1U, fwrite("2", 1, 1, fp)) << strerror(errno); 966 967 // And if we rewind, everything's there. 968 rewind(fp); 969 ASSERT_EQ(2U, fread(&buf[0], 1, buf.size(), fp)); 970 ASSERT_EQ('1', buf[0]); 971 ASSERT_EQ('2', buf[1]); 972 973 fclose(fp); 974} 975 976TEST(STDIO_TEST, fwrite_after_fread_slow_path) { 977 test_fwrite_after_fread(16); 978} 979 980TEST(STDIO_TEST, fwrite_after_fread_fast_path) { 981 test_fwrite_after_fread(64*1024); 982} 983 984// http://b/19172514 985TEST(STDIO_TEST, fread_after_fseek) { 986 TemporaryFile tf; 987 988 FILE* fp = fopen(tf.filename, "w+"); 989 ASSERT_TRUE(fp != nullptr); 990 991 char file_data[12288]; 992 for (size_t i = 0; i < 12288; i++) { 993 file_data[i] = i; 994 } 995 ASSERT_EQ(12288U, fwrite(file_data, 1, 12288, fp)); 996 fclose(fp); 997 998 fp = fopen(tf.filename, "r"); 999 ASSERT_TRUE(fp != nullptr); 1000 1001 char buffer[8192]; 1002 size_t cur_location = 0; 1003 // Small read to populate internal buffer. 1004 ASSERT_EQ(100U, fread(buffer, 1, 100, fp)); 1005 ASSERT_EQ(memcmp(file_data, buffer, 100), 0); 1006 1007 cur_location = static_cast<size_t>(ftell(fp)); 1008 // Large read to force reading into the user supplied buffer and bypassing 1009 // the internal buffer. 1010 ASSERT_EQ(8192U, fread(buffer, 1, 8192, fp)); 1011 ASSERT_EQ(memcmp(file_data+cur_location, buffer, 8192), 0); 1012 1013 // Small backwards seek to verify fseek does not reuse the internal buffer. 1014 ASSERT_EQ(0, fseek(fp, -22, SEEK_CUR)) << strerror(errno); 1015 cur_location = static_cast<size_t>(ftell(fp)); 1016 ASSERT_EQ(22U, fread(buffer, 1, 22, fp)); 1017 ASSERT_EQ(memcmp(file_data+cur_location, buffer, 22), 0); 1018 1019 fclose(fp); 1020} 1021 1022// https://code.google.com/p/android/issues/detail?id=184847 1023TEST(STDIO_TEST, fread_EOF_184847) { 1024 TemporaryFile tf; 1025 char buf[6] = {0}; 1026 1027 FILE* fw = fopen(tf.filename, "w"); 1028 ASSERT_TRUE(fw != nullptr); 1029 1030 FILE* fr = fopen(tf.filename, "r"); 1031 ASSERT_TRUE(fr != nullptr); 1032 1033 fwrite("a", 1, 1, fw); 1034 fflush(fw); 1035 ASSERT_EQ(1U, fread(buf, 1, 1, fr)); 1036 ASSERT_STREQ("a", buf); 1037 1038 // 'fr' is now at EOF. 1039 ASSERT_EQ(0U, fread(buf, 1, 1, fr)); 1040 ASSERT_TRUE(feof(fr)); 1041 1042 // Write some more... 1043 fwrite("z", 1, 1, fw); 1044 fflush(fw); 1045 1046 // ...and check that we can read it back. 1047 // (BSD thinks that once a stream has hit EOF, it must always return EOF. SysV disagrees.) 1048 ASSERT_EQ(1U, fread(buf, 1, 1, fr)); 1049 ASSERT_STREQ("z", buf); 1050 1051 // But now we're done. 1052 ASSERT_EQ(0U, fread(buf, 1, 1, fr)); 1053 1054 fclose(fr); 1055 fclose(fw); 1056} 1057 1058TEST(STDIO_TEST, fclose_invalidates_fd) { 1059 // The typical error we're trying to help people catch involves accessing 1060 // memory after it's been freed. But we know that stdin/stdout/stderr are 1061 // special and don't get deallocated, so this test uses stdin. 1062 ASSERT_EQ(0, fclose(stdin)); 1063 1064 // Even though using a FILE* after close is undefined behavior, I've closed 1065 // this bug as "WAI" too many times. We shouldn't hand out stale fds, 1066 // especially because they might actually correspond to a real stream. 1067 errno = 0; 1068 ASSERT_EQ(-1, fileno(stdin)); 1069 ASSERT_EQ(EBADF, errno); 1070} 1071 1072TEST(STDIO_TEST, fseek_ftell_unseekable) { 1073#if defined(__BIONIC__) // glibc has fopencookie instead. 1074 auto read_fn = [](void*, char*, int) { return -1; }; 1075 FILE* fp = funopen(nullptr, read_fn, nullptr, nullptr, nullptr); 1076 ASSERT_TRUE(fp != nullptr); 1077 1078 // Check that ftell balks on an unseekable FILE*. 1079 errno = 0; 1080 ASSERT_EQ(-1, ftell(fp)); 1081 ASSERT_EQ(ESPIPE, errno); 1082 1083 // SEEK_CUR is rewritten as SEEK_SET internally... 1084 errno = 0; 1085 ASSERT_EQ(-1, fseek(fp, 0, SEEK_CUR)); 1086 ASSERT_EQ(ESPIPE, errno); 1087 1088 // ...so it's worth testing the direct seek path too. 1089 errno = 0; 1090 ASSERT_EQ(-1, fseek(fp, 0, SEEK_SET)); 1091 ASSERT_EQ(ESPIPE, errno); 1092 1093 fclose(fp); 1094#else 1095 GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n"; 1096#endif 1097} 1098 1099TEST(STDIO_TEST, funopen_EINVAL) { 1100#if defined(__BIONIC__) 1101 errno = 0; 1102 ASSERT_EQ(nullptr, funopen(nullptr, nullptr, nullptr, nullptr, nullptr)); 1103 ASSERT_EQ(EINVAL, errno); 1104#else 1105 GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n"; 1106#endif 1107} 1108 1109TEST(STDIO_TEST, funopen_seek) { 1110#if defined(__BIONIC__) 1111 auto read_fn = [](void*, char*, int) { return -1; }; 1112 1113 auto seek_fn = [](void*, fpos_t, int) -> fpos_t { return 0xfedcba12; }; 1114 auto seek64_fn = [](void*, fpos64_t, int) -> fpos64_t { return 0xfedcba12345678; }; 1115 1116 FILE* fp = funopen(nullptr, read_fn, nullptr, seek_fn, nullptr); 1117 ASSERT_TRUE(fp != nullptr); 1118 fpos_t pos; 1119#if defined(__LP64__) 1120 EXPECT_EQ(0, fgetpos(fp, &pos)) << strerror(errno); 1121 EXPECT_EQ(0xfedcba12LL, pos); 1122#else 1123 EXPECT_EQ(-1, fgetpos(fp, &pos)) << strerror(errno); 1124 EXPECT_EQ(EOVERFLOW, errno); 1125#endif 1126 1127 FILE* fp64 = funopen64(nullptr, read_fn, nullptr, seek64_fn, nullptr); 1128 ASSERT_TRUE(fp64 != nullptr); 1129 fpos64_t pos64; 1130 EXPECT_EQ(0, fgetpos64(fp64, &pos64)) << strerror(errno); 1131 EXPECT_EQ(0xfedcba12345678, pos64); 1132#else 1133 GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n"; 1134#endif 1135} 1136 1137TEST(STDIO_TEST, lots_of_concurrent_files) { 1138 std::vector<TemporaryFile*> tfs; 1139 std::vector<FILE*> fps; 1140 1141 for (size_t i = 0; i < 256; ++i) { 1142 TemporaryFile* tf = new TemporaryFile; 1143 tfs.push_back(tf); 1144 FILE* fp = fopen(tf->filename, "w+"); 1145 fps.push_back(fp); 1146 fprintf(fp, "hello %zu!\n", i); 1147 fflush(fp); 1148 } 1149 1150 for (size_t i = 0; i < 256; ++i) { 1151 rewind(fps[i]); 1152 1153 char buf[BUFSIZ]; 1154 ASSERT_TRUE(fgets(buf, sizeof(buf), fps[i]) != nullptr); 1155 1156 char expected[BUFSIZ]; 1157 snprintf(expected, sizeof(expected), "hello %zu!\n", i); 1158 ASSERT_STREQ(expected, buf); 1159 1160 fclose(fps[i]); 1161 delete tfs[i]; 1162 } 1163} 1164 1165static void AssertFileOffsetAt(FILE* fp, off64_t offset) { 1166 EXPECT_EQ(offset, ftell(fp)); 1167 EXPECT_EQ(offset, ftello(fp)); 1168 EXPECT_EQ(offset, ftello64(fp)); 1169 fpos_t pos; 1170 fpos64_t pos64; 1171 EXPECT_EQ(0, fgetpos(fp, &pos)); 1172 EXPECT_EQ(0, fgetpos64(fp, &pos64)); 1173#if defined(__BIONIC__) 1174 EXPECT_EQ(offset, static_cast<off64_t>(pos)); 1175 EXPECT_EQ(offset, static_cast<off64_t>(pos64)); 1176#else 1177 GTEST_LOG_(INFO) << "glibc's fpos_t is opaque.\n"; 1178#endif 1179} 1180 1181TEST(STDIO_TEST, seek_tell_family_smoke) { 1182 TemporaryFile tf; 1183 FILE* fp = fdopen(tf.fd, "w+"); 1184 1185 // Initially we should be at 0. 1186 AssertFileOffsetAt(fp, 0); 1187 1188 // Seek to offset 8192. 1189 ASSERT_EQ(0, fseek(fp, 8192, SEEK_SET)); 1190 AssertFileOffsetAt(fp, 8192); 1191 fpos_t eight_k_pos; 1192 ASSERT_EQ(0, fgetpos(fp, &eight_k_pos)); 1193 1194 // Seek forward another 8192... 1195 ASSERT_EQ(0, fseek(fp, 8192, SEEK_CUR)); 1196 AssertFileOffsetAt(fp, 8192 + 8192); 1197 fpos64_t sixteen_k_pos64; 1198 ASSERT_EQ(0, fgetpos64(fp, &sixteen_k_pos64)); 1199 1200 // Seek back 8192... 1201 ASSERT_EQ(0, fseek(fp, -8192, SEEK_CUR)); 1202 AssertFileOffsetAt(fp, 8192); 1203 1204 // Since we haven't written anything, the end is also at 0. 1205 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1206 AssertFileOffsetAt(fp, 0); 1207 1208 // Check that our fpos64_t from 16KiB works... 1209 ASSERT_EQ(0, fsetpos64(fp, &sixteen_k_pos64)); 1210 AssertFileOffsetAt(fp, 8192 + 8192); 1211 // ...as does our fpos_t from 8192. 1212 ASSERT_EQ(0, fsetpos(fp, &eight_k_pos)); 1213 AssertFileOffsetAt(fp, 8192); 1214 1215 // Do fseeko and fseeko64 work too? 1216 ASSERT_EQ(0, fseeko(fp, 1234, SEEK_SET)); 1217 AssertFileOffsetAt(fp, 1234); 1218 ASSERT_EQ(0, fseeko64(fp, 5678, SEEK_SET)); 1219 AssertFileOffsetAt(fp, 5678); 1220 1221 fclose(fp); 1222} 1223 1224TEST(STDIO_TEST, fseek_fseeko_EINVAL) { 1225 TemporaryFile tf; 1226 FILE* fp = fdopen(tf.fd, "w+"); 1227 1228 // Bad whence. 1229 errno = 0; 1230 ASSERT_EQ(-1, fseek(fp, 0, 123)); 1231 ASSERT_EQ(EINVAL, errno); 1232 errno = 0; 1233 ASSERT_EQ(-1, fseeko(fp, 0, 123)); 1234 ASSERT_EQ(EINVAL, errno); 1235 errno = 0; 1236 ASSERT_EQ(-1, fseeko64(fp, 0, 123)); 1237 ASSERT_EQ(EINVAL, errno); 1238 1239 // Bad offset. 1240 errno = 0; 1241 ASSERT_EQ(-1, fseek(fp, -1, SEEK_SET)); 1242 ASSERT_EQ(EINVAL, errno); 1243 errno = 0; 1244 ASSERT_EQ(-1, fseeko(fp, -1, SEEK_SET)); 1245 ASSERT_EQ(EINVAL, errno); 1246 errno = 0; 1247 ASSERT_EQ(-1, fseeko64(fp, -1, SEEK_SET)); 1248 ASSERT_EQ(EINVAL, errno); 1249 1250 fclose(fp); 1251} 1252