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