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 <string>
     31 #include <vector>
     32 
     33 #include "BionicDeathTest.h"
     34 #include "TemporaryFile.h"
     35 #include "utils.h"
     36 
     37 #if defined(NOFORTIFY)
     38 #define STDIO_TEST stdio_nofortify
     39 #define STDIO_DEATHTEST stdio_nofortify_DeathTest
     40 #else
     41 #define STDIO_TEST stdio
     42 #define STDIO_DEATHTEST stdio_DeathTest
     43 #endif
     44 
     45 using namespace std::string_literals;
     46 
     47 class stdio_DeathTest : public BionicDeathTest {};
     48 class stdio_nofortify_DeathTest : public BionicDeathTest {};
     49 
     50 static void SetFileTo(const char* path, const char* content) {
     51   FILE* fp;
     52   ASSERT_NE(nullptr, fp = fopen(path, "w"));
     53   ASSERT_NE(EOF, fputs(content, fp));
     54   ASSERT_EQ(0, fclose(fp));
     55 }
     56 
     57 static void AssertFileIs(const char* path, const char* expected) {
     58   FILE* fp;
     59   ASSERT_NE(nullptr, fp = fopen(path, "r"));
     60   char* line = nullptr;
     61   size_t length;
     62   ASSERT_NE(EOF, getline(&line, &length, fp));
     63   ASSERT_EQ(0, fclose(fp));
     64   ASSERT_STREQ(expected, line);
     65   free(line);
     66 }
     67 
     68 static void AssertFileIs(FILE* fp, const char* expected, bool is_fmemopen = false) {
     69   rewind(fp);
     70 
     71   char line[1024];
     72   memset(line, 0xff, sizeof(line));
     73   ASSERT_EQ(line, fgets(line, sizeof(line), fp));
     74   ASSERT_STREQ(expected, line);
     75 
     76   if (is_fmemopen) {
     77     // fmemopen appends a trailing NUL byte, which probably shouldn't show up as an
     78     // extra empty line, but does on every C library I tested...
     79     ASSERT_EQ(line, fgets(line, sizeof(line), fp));
     80     ASSERT_STREQ("", line);
     81   }
     82 
     83   // Make sure there isn't anything else in the file.
     84   ASSERT_EQ(nullptr, fgets(line, sizeof(line), fp)) << "junk at end of file: " << line;
     85 }
     86 
     87 TEST(STDIO_TEST, flockfile_18208568_stderr) {
     88   // Check that we have a _recursive_ mutex for flockfile.
     89   flockfile(stderr);
     90   feof(stderr); // We don't care about the result, but this needs to take the lock.
     91   funlockfile(stderr);
     92 }
     93 
     94 TEST(STDIO_TEST, flockfile_18208568_regular) {
     95   // We never had a bug for streams other than stdin/stdout/stderr, but test anyway.
     96   FILE* fp = fopen("/dev/null", "w");
     97   ASSERT_TRUE(fp != NULL);
     98   flockfile(fp);
     99   feof(fp);
    100   funlockfile(fp);
    101   fclose(fp);
    102 }
    103 
    104 TEST(STDIO_TEST, tmpfile_fileno_fprintf_rewind_fgets) {
    105   FILE* fp = tmpfile();
    106   ASSERT_TRUE(fp != NULL);
    107 
    108   int fd = fileno(fp);
    109   ASSERT_NE(fd, -1);
    110 
    111   struct stat sb;
    112   int rc = fstat(fd, &sb);
    113   ASSERT_NE(rc, -1);
    114   ASSERT_EQ(sb.st_mode & 0777, 0600U);
    115 
    116   rc = fprintf(fp, "hello\n");
    117   ASSERT_EQ(rc, 6);
    118 
    119   AssertFileIs(fp, "hello\n");
    120   fclose(fp);
    121 }
    122 
    123 TEST(STDIO_TEST, tmpfile64) {
    124   FILE* fp = tmpfile64();
    125   ASSERT_TRUE(fp != nullptr);
    126   fclose(fp);
    127 }
    128 
    129 TEST(STDIO_TEST, dprintf) {
    130   TemporaryFile tf;
    131 
    132   int rc = dprintf(tf.fd, "hello\n");
    133   ASSERT_EQ(rc, 6);
    134 
    135   lseek(tf.fd, 0, SEEK_SET);
    136   FILE* tfile = fdopen(tf.fd, "r");
    137   ASSERT_TRUE(tfile != NULL);
    138 
    139   AssertFileIs(tfile, "hello\n");
    140   fclose(tfile);
    141 }
    142 
    143 TEST(STDIO_TEST, getdelim) {
    144   FILE* fp = tmpfile();
    145   ASSERT_TRUE(fp != NULL);
    146 
    147   const char* line_written = "This  is a test";
    148   int rc = fprintf(fp, "%s", line_written);
    149   ASSERT_EQ(rc, static_cast<int>(strlen(line_written)));
    150 
    151   rewind(fp);
    152 
    153   char* word_read = NULL;
    154   size_t allocated_length = 0;
    155 
    156   const char* expected[] = { "This ", " ", "is ", "a ", "test" };
    157   for (size_t i = 0; i < 5; ++i) {
    158     ASSERT_FALSE(feof(fp));
    159     ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), static_cast<int>(strlen(expected[i])));
    160     ASSERT_GE(allocated_length, strlen(expected[i]));
    161     ASSERT_STREQ(expected[i], word_read);
    162   }
    163   // The last read should have set the end-of-file indicator for the stream.
    164   ASSERT_TRUE(feof(fp));
    165   clearerr(fp);
    166 
    167   // getdelim returns -1 but doesn't set errno if we're already at EOF.
    168   // It should set the end-of-file indicator for the stream, though.
    169   errno = 0;
    170   ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), -1);
    171   ASSERT_EQ(0, errno);
    172   ASSERT_TRUE(feof(fp));
    173 
    174   free(word_read);
    175   fclose(fp);
    176 }
    177 
    178 TEST(STDIO_TEST, getdelim_invalid) {
    179   FILE* fp = tmpfile();
    180   ASSERT_TRUE(fp != NULL);
    181 
    182   char* buffer = NULL;
    183   size_t buffer_length = 0;
    184 
    185   // The first argument can't be NULL.
    186   errno = 0;
    187   ASSERT_EQ(getdelim(NULL, &buffer_length, ' ', fp), -1);
    188   ASSERT_EQ(EINVAL, errno);
    189 
    190   // The second argument can't be NULL.
    191   errno = 0;
    192   ASSERT_EQ(getdelim(&buffer, NULL, ' ', fp), -1);
    193   ASSERT_EQ(EINVAL, errno);
    194 
    195   // The underlying fd can't be closed.
    196   ASSERT_EQ(0, close(fileno(fp)));
    197   errno = 0;
    198   ASSERT_EQ(getdelim(&buffer, &buffer_length, ' ', fp), -1);
    199   ASSERT_EQ(EBADF, errno);
    200   fclose(fp);
    201 }
    202 
    203 TEST(STDIO_TEST, getdelim_directory) {
    204   FILE* fp = fopen("/proc", "r");
    205   ASSERT_TRUE(fp != NULL);
    206   char* word_read;
    207   size_t allocated_length;
    208   ASSERT_EQ(-1, getdelim(&word_read, &allocated_length, ' ', fp));
    209   fclose(fp);
    210 }
    211 
    212 TEST(STDIO_TEST, getline) {
    213   FILE* fp = tmpfile();
    214   ASSERT_TRUE(fp != NULL);
    215 
    216   const char* line_written = "This is a test for getline\n";
    217   const size_t line_count = 5;
    218 
    219   for (size_t i = 0; i < line_count; ++i) {
    220     int rc = fprintf(fp, "%s", line_written);
    221     ASSERT_EQ(rc, static_cast<int>(strlen(line_written)));
    222   }
    223 
    224   rewind(fp);
    225 
    226   char* line_read = NULL;
    227   size_t allocated_length = 0;
    228 
    229   size_t read_line_count = 0;
    230   ssize_t read_char_count;
    231   while ((read_char_count = getline(&line_read, &allocated_length, fp)) != -1) {
    232     ASSERT_EQ(read_char_count, static_cast<int>(strlen(line_written)));
    233     ASSERT_GE(allocated_length, strlen(line_written));
    234     ASSERT_STREQ(line_written, line_read);
    235     ++read_line_count;
    236   }
    237   ASSERT_EQ(read_line_count, line_count);
    238 
    239   // The last read should have set the end-of-file indicator for the stream.
    240   ASSERT_TRUE(feof(fp));
    241   clearerr(fp);
    242 
    243   // getline returns -1 but doesn't set errno if we're already at EOF.
    244   // It should set the end-of-file indicator for the stream, though.
    245   errno = 0;
    246   ASSERT_EQ(getline(&line_read, &allocated_length, fp), -1);
    247   ASSERT_EQ(0, errno);
    248   ASSERT_TRUE(feof(fp));
    249 
    250   free(line_read);
    251   fclose(fp);
    252 }
    253 
    254 TEST(STDIO_TEST, getline_invalid) {
    255   FILE* fp = tmpfile();
    256   ASSERT_TRUE(fp != NULL);
    257 
    258   char* buffer = NULL;
    259   size_t buffer_length = 0;
    260 
    261   // The first argument can't be NULL.
    262   errno = 0;
    263   ASSERT_EQ(getline(NULL, &buffer_length, fp), -1);
    264   ASSERT_EQ(EINVAL, errno);
    265 
    266   // The second argument can't be NULL.
    267   errno = 0;
    268   ASSERT_EQ(getline(&buffer, NULL, fp), -1);
    269   ASSERT_EQ(EINVAL, errno);
    270 
    271   // The underlying fd can't be closed.
    272   ASSERT_EQ(0, close(fileno(fp)));
    273   errno = 0;
    274   ASSERT_EQ(getline(&buffer, &buffer_length, fp), -1);
    275   ASSERT_EQ(EBADF, errno);
    276   fclose(fp);
    277 }
    278 
    279 TEST(STDIO_TEST, printf_ssize_t) {
    280   // http://b/8253769
    281   ASSERT_EQ(sizeof(ssize_t), sizeof(long int));
    282   ASSERT_EQ(sizeof(ssize_t), sizeof(size_t));
    283   // For our 32-bit ABI, we had a ssize_t definition that confuses GCC into saying:
    284   // error: format '%zd' expects argument of type 'signed size_t',
    285   //     but argument 4 has type 'ssize_t {aka long int}' [-Werror=format]
    286   ssize_t v = 1;
    287   char buf[32];
    288   snprintf(buf, sizeof(buf), "%zd", v);
    289 }
    290 
    291 // https://code.google.com/p/android/issues/detail?id=64886
    292 TEST(STDIO_TEST, snprintf_a) {
    293   char buf[BUFSIZ];
    294   EXPECT_EQ(23, snprintf(buf, sizeof(buf), "<%a>", 9990.235));
    295   EXPECT_STREQ("<0x1.3831e147ae148p+13>", buf);
    296 }
    297 
    298 TEST(STDIO_TEST, snprintf_lc) {
    299   char buf[BUFSIZ];
    300   wint_t wc = L'a';
    301   EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%lc>", wc));
    302   EXPECT_STREQ("<a>", buf);
    303 }
    304 
    305 TEST(STDIO_TEST, snprintf_C) { // Synonym for %lc.
    306   char buf[BUFSIZ];
    307   wchar_t wc = L'a';
    308   EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%C>", wc));
    309   EXPECT_STREQ("<a>", buf);
    310 }
    311 
    312 TEST(STDIO_TEST, snprintf_ls) {
    313   char buf[BUFSIZ];
    314   wchar_t* ws = NULL;
    315   EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%ls>", ws));
    316   EXPECT_STREQ("<(null)>", buf);
    317 
    318   wchar_t chars[] = { L'h', L'i', 0 };
    319   ws = chars;
    320   EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%ls>", ws));
    321   EXPECT_STREQ("<hi>", buf);
    322 }
    323 
    324 TEST(STDIO_TEST, snprintf_S) { // Synonym for %ls.
    325   char buf[BUFSIZ];
    326   wchar_t* ws = NULL;
    327   EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%S>", ws));
    328   EXPECT_STREQ("<(null)>", buf);
    329 
    330   wchar_t chars[] = { L'h', L'i', 0 };
    331   ws = chars;
    332   EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%S>", ws));
    333   EXPECT_STREQ("<hi>", buf);
    334 }
    335 
    336 TEST(STDIO_TEST, snprintf_n) {
    337 #if defined(__BIONIC__)
    338   // http://b/14492135
    339   char buf[32];
    340   int i = 1234;
    341   EXPECT_EQ(5, snprintf(buf, sizeof(buf), "a %n b", &i));
    342   EXPECT_EQ(1234, i);
    343   EXPECT_STREQ("a n b", buf);
    344 #else
    345   GTEST_LOG_(INFO) << "This test does nothing on glibc.\n";
    346 #endif
    347 }
    348 
    349 TEST(STDIO_TEST, snprintf_smoke) {
    350   char buf[BUFSIZ];
    351 
    352   snprintf(buf, sizeof(buf), "a");
    353   EXPECT_STREQ("a", buf);
    354 
    355   snprintf(buf, sizeof(buf), "%%");
    356   EXPECT_STREQ("%", buf);
    357 
    358   snprintf(buf, sizeof(buf), "01234");
    359   EXPECT_STREQ("01234", buf);
    360 
    361   snprintf(buf, sizeof(buf), "a%sb", "01234");
    362   EXPECT_STREQ("a01234b", buf);
    363 
    364   char* s = NULL;
    365   snprintf(buf, sizeof(buf), "a%sb", s);
    366   EXPECT_STREQ("a(null)b", buf);
    367 
    368   snprintf(buf, sizeof(buf), "aa%scc", "bb");
    369   EXPECT_STREQ("aabbcc", buf);
    370 
    371   snprintf(buf, sizeof(buf), "a%cc", 'b');
    372   EXPECT_STREQ("abc", buf);
    373 
    374   snprintf(buf, sizeof(buf), "a%db", 1234);
    375   EXPECT_STREQ("a1234b", buf);
    376 
    377   snprintf(buf, sizeof(buf), "a%db", -8123);
    378   EXPECT_STREQ("a-8123b", buf);
    379 
    380   snprintf(buf, sizeof(buf), "a%hdb", static_cast<short>(0x7fff0010));
    381   EXPECT_STREQ("a16b", buf);
    382 
    383   snprintf(buf, sizeof(buf), "a%hhdb", static_cast<char>(0x7fffff10));
    384   EXPECT_STREQ("a16b", buf);
    385 
    386   snprintf(buf, sizeof(buf), "a%lldb", 0x1000000000LL);
    387   EXPECT_STREQ("a68719476736b", buf);
    388 
    389   snprintf(buf, sizeof(buf), "a%ldb", 70000L);
    390   EXPECT_STREQ("a70000b", buf);
    391 
    392   snprintf(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234));
    393   EXPECT_STREQ("a0xb0001234b", buf);
    394 
    395   snprintf(buf, sizeof(buf), "a%xz", 0x12ab);
    396   EXPECT_STREQ("a12abz", buf);
    397 
    398   snprintf(buf, sizeof(buf), "a%Xz", 0x12ab);
    399   EXPECT_STREQ("a12ABz", buf);
    400 
    401   snprintf(buf, sizeof(buf), "a%08xz", 0x123456);
    402   EXPECT_STREQ("a00123456z", buf);
    403 
    404   snprintf(buf, sizeof(buf), "a%5dz", 1234);
    405   EXPECT_STREQ("a 1234z", buf);
    406 
    407   snprintf(buf, sizeof(buf), "a%05dz", 1234);
    408   EXPECT_STREQ("a01234z", buf);
    409 
    410   snprintf(buf, sizeof(buf), "a%8dz", 1234);
    411   EXPECT_STREQ("a    1234z", buf);
    412 
    413   snprintf(buf, sizeof(buf), "a%-8dz", 1234);
    414   EXPECT_STREQ("a1234    z", buf);
    415 
    416   snprintf(buf, sizeof(buf), "A%-11sZ", "abcdef");
    417   EXPECT_STREQ("Aabcdef     Z", buf);
    418 
    419   snprintf(buf, sizeof(buf), "A%s:%dZ", "hello", 1234);
    420   EXPECT_STREQ("Ahello:1234Z", buf);
    421 
    422   snprintf(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5);
    423   EXPECT_STREQ("a005:5:05z", buf);
    424 
    425   void* p = NULL;
    426   snprintf(buf, sizeof(buf), "a%d,%pz", 5, p);
    427 #if defined(__BIONIC__)
    428   EXPECT_STREQ("a5,0x0z", buf);
    429 #else // __BIONIC__
    430   EXPECT_STREQ("a5,(nil)z", buf);
    431 #endif // __BIONIC__
    432 
    433   snprintf(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8);
    434   EXPECT_STREQ("a68719476736,6,7,8z", buf);
    435 
    436   snprintf(buf, sizeof(buf), "a_%f_b", 1.23f);
    437   EXPECT_STREQ("a_1.230000_b", buf);
    438 
    439   snprintf(buf, sizeof(buf), "a_%g_b", 3.14);
    440   EXPECT_STREQ("a_3.14_b", buf);
    441 
    442   snprintf(buf, sizeof(buf), "%1$s %1$s", "print_me_twice");
    443   EXPECT_STREQ("print_me_twice print_me_twice", buf);
    444 }
    445 
    446 template <typename T>
    447 static void CheckInfNan(int snprintf_fn(T*, size_t, const T*, ...),
    448                         int sscanf_fn(const T*, const T*, ...),
    449                         const T* fmt_string, const T* fmt, const T* fmt_plus,
    450                         const T* minus_inf, const T* inf_, const T* plus_inf,
    451                         const T* minus_nan, const T* nan_, const T* plus_nan) {
    452   T buf[BUFSIZ];
    453   float f;
    454 
    455   // NaN.
    456 
    457   snprintf_fn(buf, sizeof(buf), fmt, nanf(""));
    458   EXPECT_STREQ(nan_, buf) << fmt;
    459   EXPECT_EQ(1, sscanf_fn(buf, fmt, &f));
    460   EXPECT_TRUE(isnan(f));
    461 
    462   snprintf_fn(buf, sizeof(buf), fmt, -nanf(""));
    463   EXPECT_STREQ(minus_nan, buf) << fmt;
    464   EXPECT_EQ(1, sscanf_fn(buf, fmt, &f));
    465   EXPECT_TRUE(isnan(f));
    466 
    467   snprintf_fn(buf, sizeof(buf), fmt_plus, nanf(""));
    468   EXPECT_STREQ(plus_nan, buf) << fmt_plus;
    469   EXPECT_EQ(1, sscanf_fn(buf, fmt, &f));
    470   EXPECT_TRUE(isnan(f));
    471 
    472   snprintf_fn(buf, sizeof(buf), fmt_plus, -nanf(""));
    473   EXPECT_STREQ(minus_nan, buf) << fmt_plus;
    474   EXPECT_EQ(1, sscanf_fn(buf, fmt, &f));
    475   EXPECT_TRUE(isnan(f));
    476 
    477   // Inf.
    478 
    479   snprintf_fn(buf, sizeof(buf), fmt, HUGE_VALF);
    480   EXPECT_STREQ(inf_, buf) << fmt;
    481   EXPECT_EQ(1, sscanf_fn(buf, fmt, &f));
    482   EXPECT_EQ(HUGE_VALF, f);
    483 
    484   snprintf_fn(buf, sizeof(buf), fmt, -HUGE_VALF);
    485   EXPECT_STREQ(minus_inf, buf) << fmt;
    486   EXPECT_EQ(1, sscanf_fn(buf, fmt, &f));
    487   EXPECT_EQ(-HUGE_VALF, f);
    488 
    489   snprintf_fn(buf, sizeof(buf), fmt_plus, HUGE_VALF);
    490   EXPECT_STREQ(plus_inf, buf) << fmt_plus;
    491   EXPECT_EQ(1, sscanf_fn(buf, fmt, &f));
    492   EXPECT_EQ(HUGE_VALF, f);
    493 
    494   snprintf_fn(buf, sizeof(buf), fmt_plus, -HUGE_VALF);
    495   EXPECT_STREQ(minus_inf, buf) << fmt_plus;
    496   EXPECT_EQ(1, sscanf_fn(buf, fmt, &f));
    497   EXPECT_EQ(-HUGE_VALF, f);
    498 
    499   // Check case-insensitivity.
    500   snprintf_fn(buf, sizeof(buf), fmt_string, "[InFiNiTy]");
    501   EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)) << buf;
    502   EXPECT_EQ(HUGE_VALF, f);
    503   snprintf_fn(buf, sizeof(buf), fmt_string, "[NaN]");
    504   EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)) << buf;
    505   EXPECT_TRUE(isnan(f));
    506 }
    507 
    508 TEST(STDIO_TEST, snprintf_sscanf_inf_nan) {
    509   CheckInfNan(snprintf, sscanf, "%s",
    510               "[%a]", "[%+a]",
    511               "[-inf]", "[inf]", "[+inf]",
    512               "[-nan]", "[nan]", "[+nan]");
    513   CheckInfNan(snprintf, sscanf, "%s",
    514               "[%A]", "[%+A]",
    515               "[-INF]", "[INF]", "[+INF]",
    516               "[-NAN]", "[NAN]", "[+NAN]");
    517   CheckInfNan(snprintf, sscanf, "%s",
    518               "[%e]", "[%+e]",
    519               "[-inf]", "[inf]", "[+inf]",
    520               "[-nan]", "[nan]", "[+nan]");
    521   CheckInfNan(snprintf, sscanf, "%s",
    522               "[%E]", "[%+E]",
    523               "[-INF]", "[INF]", "[+INF]",
    524               "[-NAN]", "[NAN]", "[+NAN]");
    525   CheckInfNan(snprintf, sscanf, "%s",
    526               "[%f]", "[%+f]",
    527               "[-inf]", "[inf]", "[+inf]",
    528               "[-nan]", "[nan]", "[+nan]");
    529   CheckInfNan(snprintf, sscanf, "%s",
    530               "[%F]", "[%+F]",
    531               "[-INF]", "[INF]", "[+INF]",
    532               "[-NAN]", "[NAN]", "[+NAN]");
    533   CheckInfNan(snprintf, sscanf, "%s",
    534               "[%g]", "[%+g]",
    535               "[-inf]", "[inf]", "[+inf]",
    536               "[-nan]", "[nan]", "[+nan]");
    537   CheckInfNan(snprintf, sscanf, "%s",
    538               "[%G]", "[%+G]",
    539               "[-INF]", "[INF]", "[+INF]",
    540               "[-NAN]", "[NAN]", "[+NAN]");
    541 }
    542 
    543 TEST(STDIO_TEST, swprintf_swscanf_inf_nan) {
    544   CheckInfNan(swprintf, swscanf, L"%s",
    545               L"[%a]", L"[%+a]",
    546               L"[-inf]", L"[inf]", L"[+inf]",
    547               L"[-nan]", L"[nan]", L"[+nan]");
    548   CheckInfNan(swprintf, swscanf, L"%s",
    549               L"[%A]", L"[%+A]",
    550               L"[-INF]", L"[INF]", L"[+INF]",
    551               L"[-NAN]", L"[NAN]", L"[+NAN]");
    552   CheckInfNan(swprintf, swscanf, L"%s",
    553               L"[%e]", L"[%+e]",
    554               L"[-inf]", L"[inf]", L"[+inf]",
    555               L"[-nan]", L"[nan]", L"[+nan]");
    556   CheckInfNan(swprintf, swscanf, L"%s",
    557               L"[%E]", L"[%+E]",
    558               L"[-INF]", L"[INF]", L"[+INF]",
    559               L"[-NAN]", L"[NAN]", L"[+NAN]");
    560   CheckInfNan(swprintf, swscanf, L"%s",
    561               L"[%f]", L"[%+f]",
    562               L"[-inf]", L"[inf]", L"[+inf]",
    563               L"[-nan]", L"[nan]", L"[+nan]");
    564   CheckInfNan(swprintf, swscanf, L"%s",
    565               L"[%F]", L"[%+F]",
    566               L"[-INF]", L"[INF]", L"[+INF]",
    567               L"[-NAN]", L"[NAN]", L"[+NAN]");
    568   CheckInfNan(swprintf, swscanf, L"%s",
    569               L"[%g]", L"[%+g]",
    570               L"[-inf]", L"[inf]", L"[+inf]",
    571               L"[-nan]", L"[nan]", L"[+nan]");
    572   CheckInfNan(swprintf, swscanf, L"%s",
    573               L"[%G]", L"[%+G]",
    574               L"[-INF]", L"[INF]", L"[+INF]",
    575               L"[-NAN]", L"[NAN]", L"[+NAN]");
    576 }
    577 
    578 TEST(STDIO_TEST, swprintf) {
    579   constexpr size_t nchars = 32;
    580   wchar_t buf[nchars];
    581 
    582   ASSERT_EQ(2, swprintf(buf, nchars, L"ab")) << strerror(errno);
    583   ASSERT_EQ(std::wstring(L"ab"), buf);
    584   ASSERT_EQ(5, swprintf(buf, nchars, L"%s", "abcde"));
    585   ASSERT_EQ(std::wstring(L"abcde"), buf);
    586 
    587   // Unlike swprintf(), swprintf() returns -1 in case of truncation
    588   // and doesn't necessarily zero-terminate the output!
    589   ASSERT_EQ(-1, swprintf(buf, 4, L"%s", "abcde"));
    590 
    591   const char kString[] = "Hello, World";
    592   ASSERT_EQ(12, swprintf(buf, nchars, L"%s", kString));
    593   ASSERT_EQ(std::wstring(L"Hello, World"), buf);
    594   ASSERT_EQ(12, swprintf(buf, 13, L"%s", kString));
    595   ASSERT_EQ(std::wstring(L"Hello, World"), buf);
    596 }
    597 
    598 TEST(STDIO_TEST, swprintf_a) {
    599   constexpr size_t nchars = 32;
    600   wchar_t buf[nchars];
    601 
    602   ASSERT_EQ(20, swprintf(buf, nchars, L"%a", 3.1415926535));
    603   ASSERT_EQ(std::wstring(L"0x1.921fb54411744p+1"), buf);
    604 }
    605 
    606 TEST(STDIO_TEST, swprintf_lc) {
    607   constexpr size_t nchars = 32;
    608   wchar_t buf[nchars];
    609 
    610   wint_t wc = L'a';
    611   EXPECT_EQ(3, swprintf(buf, nchars, L"<%lc>", wc));
    612   EXPECT_EQ(std::wstring(L"<a>"), buf);
    613 }
    614 
    615 TEST(STDIO_TEST, swprintf_C) { // Synonym for %lc.
    616   constexpr size_t nchars = 32;
    617   wchar_t buf[nchars];
    618 
    619   wint_t wc = L'a';
    620   EXPECT_EQ(3, swprintf(buf, nchars, L"<%C>", wc));
    621   EXPECT_EQ(std::wstring(L"<a>"), buf);
    622 }
    623 
    624 TEST(STDIO_TEST, swprintf_jd_INTMAX_MAX) {
    625   constexpr size_t nchars = 32;
    626   wchar_t buf[nchars];
    627 
    628   swprintf(buf, nchars, L"%jd", INTMAX_MAX);
    629   EXPECT_EQ(std::wstring(L"9223372036854775807"), buf);
    630 }
    631 
    632 TEST(STDIO_TEST, swprintf_jd_INTMAX_MIN) {
    633   constexpr size_t nchars = 32;
    634   wchar_t buf[nchars];
    635 
    636   swprintf(buf, nchars, L"%jd", INTMAX_MIN);
    637   EXPECT_EQ(std::wstring(L"-9223372036854775808"), buf);
    638 }
    639 
    640 TEST(STDIO_TEST, swprintf_ju_UINTMAX_MAX) {
    641   constexpr size_t nchars = 32;
    642   wchar_t buf[nchars];
    643 
    644   swprintf(buf, nchars, L"%ju", UINTMAX_MAX);
    645   EXPECT_EQ(std::wstring(L"18446744073709551615"), buf);
    646 }
    647 
    648 TEST(STDIO_TEST, swprintf_1$ju_UINTMAX_MAX) {
    649   constexpr size_t nchars = 32;
    650   wchar_t buf[nchars];
    651 
    652   swprintf(buf, nchars, L"%1$ju", UINTMAX_MAX);
    653   EXPECT_EQ(std::wstring(L"18446744073709551615"), buf);
    654 }
    655 
    656 TEST(STDIO_TEST, swprintf_ls) {
    657   constexpr size_t nchars = 32;
    658   wchar_t buf[nchars];
    659 
    660   static const wchar_t kWideString[] = L"Hello\uff41 World";
    661   ASSERT_EQ(12, swprintf(buf, nchars, L"%ls", kWideString));
    662   ASSERT_EQ(std::wstring(kWideString), buf);
    663   ASSERT_EQ(12, swprintf(buf, 13, L"%ls", kWideString));
    664   ASSERT_EQ(std::wstring(kWideString), buf);
    665 }
    666 
    667 TEST(STDIO_TEST, swprintf_S) { // Synonym for %ls.
    668   constexpr size_t nchars = 32;
    669   wchar_t buf[nchars];
    670 
    671   static const wchar_t kWideString[] = L"Hello\uff41 World";
    672   ASSERT_EQ(12, swprintf(buf, nchars, L"%S", kWideString));
    673   ASSERT_EQ(std::wstring(kWideString), buf);
    674   ASSERT_EQ(12, swprintf(buf, 13, L"%S", kWideString));
    675   ASSERT_EQ(std::wstring(kWideString), buf);
    676 }
    677 
    678 TEST(STDIO_TEST, snprintf_d_INT_MAX) {
    679   char buf[BUFSIZ];
    680   snprintf(buf, sizeof(buf), "%d", INT_MAX);
    681   EXPECT_STREQ("2147483647", buf);
    682 }
    683 
    684 TEST(STDIO_TEST, snprintf_d_INT_MIN) {
    685   char buf[BUFSIZ];
    686   snprintf(buf, sizeof(buf), "%d", INT_MIN);
    687   EXPECT_STREQ("-2147483648", buf);
    688 }
    689 
    690 TEST(STDIO_TEST, snprintf_jd_INTMAX_MAX) {
    691   char buf[BUFSIZ];
    692   snprintf(buf, sizeof(buf), "%jd", INTMAX_MAX);
    693   EXPECT_STREQ("9223372036854775807", buf);
    694 }
    695 
    696 TEST(STDIO_TEST, snprintf_jd_INTMAX_MIN) {
    697   char buf[BUFSIZ];
    698   snprintf(buf, sizeof(buf), "%jd", INTMAX_MIN);
    699   EXPECT_STREQ("-9223372036854775808", buf);
    700 }
    701 
    702 TEST(STDIO_TEST, snprintf_ju_UINTMAX_MAX) {
    703   char buf[BUFSIZ];
    704   snprintf(buf, sizeof(buf), "%ju", UINTMAX_MAX);
    705   EXPECT_STREQ("18446744073709551615", buf);
    706 }
    707 
    708 TEST(STDIO_TEST, snprintf_1$ju_UINTMAX_MAX) {
    709   char buf[BUFSIZ];
    710   snprintf(buf, sizeof(buf), "%1$ju", UINTMAX_MAX);
    711   EXPECT_STREQ("18446744073709551615", buf);
    712 }
    713 
    714 TEST(STDIO_TEST, snprintf_ld_LONG_MAX) {
    715   char buf[BUFSIZ];
    716   snprintf(buf, sizeof(buf), "%ld", LONG_MAX);
    717 #if defined(__LP64__)
    718   EXPECT_STREQ("9223372036854775807", buf);
    719 #else
    720   EXPECT_STREQ("2147483647", buf);
    721 #endif
    722 }
    723 
    724 TEST(STDIO_TEST, snprintf_ld_LONG_MIN) {
    725   char buf[BUFSIZ];
    726   snprintf(buf, sizeof(buf), "%ld", LONG_MIN);
    727 #if defined(__LP64__)
    728   EXPECT_STREQ("-9223372036854775808", buf);
    729 #else
    730   EXPECT_STREQ("-2147483648", buf);
    731 #endif
    732 }
    733 
    734 TEST(STDIO_TEST, snprintf_lld_LLONG_MAX) {
    735   char buf[BUFSIZ];
    736   snprintf(buf, sizeof(buf), "%lld", LLONG_MAX);
    737   EXPECT_STREQ("9223372036854775807", buf);
    738 }
    739 
    740 TEST(STDIO_TEST, snprintf_lld_LLONG_MIN) {
    741   char buf[BUFSIZ];
    742   snprintf(buf, sizeof(buf), "%lld", LLONG_MIN);
    743   EXPECT_STREQ("-9223372036854775808", buf);
    744 }
    745 
    746 TEST(STDIO_TEST, snprintf_o_UINT_MAX) {
    747   char buf[BUFSIZ];
    748   snprintf(buf, sizeof(buf), "%o", UINT_MAX);
    749   EXPECT_STREQ("37777777777", buf);
    750 }
    751 
    752 TEST(STDIO_TEST, snprintf_u_UINT_MAX) {
    753   char buf[BUFSIZ];
    754   snprintf(buf, sizeof(buf), "%u", UINT_MAX);
    755   EXPECT_STREQ("4294967295", buf);
    756 }
    757 
    758 TEST(STDIO_TEST, snprintf_x_UINT_MAX) {
    759   char buf[BUFSIZ];
    760   snprintf(buf, sizeof(buf), "%x", UINT_MAX);
    761   EXPECT_STREQ("ffffffff", buf);
    762 }
    763 
    764 TEST(STDIO_TEST, snprintf_X_UINT_MAX) {
    765   char buf[BUFSIZ];
    766   snprintf(buf, sizeof(buf), "%X", UINT_MAX);
    767   EXPECT_STREQ("FFFFFFFF", buf);
    768 }
    769 
    770 TEST(STDIO_TEST, snprintf_e) {
    771   char buf[BUFSIZ];
    772 
    773   snprintf(buf, sizeof(buf), "%e", 1.5);
    774   EXPECT_STREQ("1.500000e+00", buf);
    775 
    776   snprintf(buf, sizeof(buf), "%Le", 1.5l);
    777   EXPECT_STREQ("1.500000e+00", buf);
    778 }
    779 
    780 TEST(STDIO_TEST, snprintf_negative_zero_5084292) {
    781   char buf[BUFSIZ];
    782 
    783   snprintf(buf, sizeof(buf), "%e", -0.0);
    784   EXPECT_STREQ("-0.000000e+00", buf);
    785   snprintf(buf, sizeof(buf), "%E", -0.0);
    786   EXPECT_STREQ("-0.000000E+00", buf);
    787   snprintf(buf, sizeof(buf), "%f", -0.0);
    788   EXPECT_STREQ("-0.000000", buf);
    789   snprintf(buf, sizeof(buf), "%F", -0.0);
    790   EXPECT_STREQ("-0.000000", buf);
    791   snprintf(buf, sizeof(buf), "%g", -0.0);
    792   EXPECT_STREQ("-0", buf);
    793   snprintf(buf, sizeof(buf), "%G", -0.0);
    794   EXPECT_STREQ("-0", buf);
    795   snprintf(buf, sizeof(buf), "%a", -0.0);
    796   EXPECT_STREQ("-0x0p+0", buf);
    797   snprintf(buf, sizeof(buf), "%A", -0.0);
    798   EXPECT_STREQ("-0X0P+0", buf);
    799 }
    800 
    801 TEST(STDIO_TEST, snprintf_utf8_15439554) {
    802   locale_t cloc = newlocale(LC_ALL, "C.UTF-8", 0);
    803   locale_t old_locale = uselocale(cloc);
    804 
    805   // http://b/15439554
    806   char buf[BUFSIZ];
    807 
    808   // 1-byte character.
    809   snprintf(buf, sizeof(buf), "%dx%d", 1, 2);
    810   EXPECT_STREQ("1x2", buf);
    811   // 2-byte character.
    812   snprintf(buf, sizeof(buf), "%d\xc2\xa2%d", 1, 2);
    813   EXPECT_STREQ("12", buf);
    814   // 3-byte character.
    815   snprintf(buf, sizeof(buf), "%d\xe2\x82\xac%d", 1, 2);
    816   EXPECT_STREQ("12", buf);
    817   // 4-byte character.
    818   snprintf(buf, sizeof(buf), "%d\xf0\xa4\xad\xa2%d", 1, 2);
    819   EXPECT_STREQ("12", buf);
    820 
    821   uselocale(old_locale);
    822   freelocale(cloc);
    823 }
    824 
    825 static void* snprintf_small_stack_fn(void*) {
    826   // Make life (realistically) hard for ourselves by allocating our own buffer for the result.
    827   char buf[PATH_MAX];
    828   snprintf(buf, sizeof(buf), "/proc/%d", getpid());
    829   return nullptr;
    830 }
    831 
    832 TEST(STDIO_TEST, snprintf_small_stack) {
    833   // Is it safe to call snprintf on a thread with a small stack?
    834   // (The snprintf implementation puts some pretty large buffers on the stack.)
    835   pthread_attr_t a;
    836   ASSERT_EQ(0, pthread_attr_init(&a));
    837   ASSERT_EQ(0, pthread_attr_setstacksize(&a, PTHREAD_STACK_MIN));
    838 
    839   pthread_t t;
    840   ASSERT_EQ(0, pthread_create(&t, &a, snprintf_small_stack_fn, nullptr));
    841   ASSERT_EQ(0, pthread_join(t, nullptr));
    842 }
    843 
    844 TEST(STDIO_TEST, snprintf_asterisk_overflow) {
    845   char buf[128];
    846   ASSERT_EQ(5, snprintf(buf, sizeof(buf), "%.*s%c", 4, "hello world", '!'));
    847   ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX/2, "hello world", '!'));
    848   ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX-1, "hello world", '!'));
    849   ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX, "hello world", '!'));
    850   ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", -1, "hello world", '!'));
    851 
    852   // INT_MAX-1, INT_MAX, INT_MAX+1.
    853   ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.2147483646s%c", "hello world", '!'));
    854   ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.2147483647s%c", "hello world", '!'));
    855   ASSERT_EQ(-1, snprintf(buf, sizeof(buf), "%.2147483648s%c", "hello world", '!'));
    856   ASSERT_EQ(ENOMEM, errno);
    857 }
    858 
    859 TEST(STDIO_TEST, fprintf) {
    860   TemporaryFile tf;
    861 
    862   FILE* tfile = fdopen(tf.fd, "r+");
    863   ASSERT_TRUE(tfile != nullptr);
    864 
    865   ASSERT_EQ(7, fprintf(tfile, "%d %s", 123, "abc"));
    866   AssertFileIs(tfile, "123 abc");
    867   fclose(tfile);
    868 }
    869 
    870 TEST(STDIO_TEST, fprintf_failures_7229520) {
    871   // http://b/7229520
    872   FILE* fp;
    873 
    874   // Unbuffered case where the fprintf(3) itself fails.
    875   ASSERT_NE(nullptr, fp = tmpfile());
    876   setbuf(fp, NULL);
    877   ASSERT_EQ(4, fprintf(fp, "epic"));
    878   ASSERT_EQ(0, close(fileno(fp)));
    879   ASSERT_EQ(-1, fprintf(fp, "fail"));
    880   ASSERT_EQ(-1, fclose(fp));
    881 
    882   // Buffered case where we won't notice until the fclose(3).
    883   // It's likely this is what was actually seen in http://b/7229520,
    884   // and that expecting fprintf to fail is setting yourself up for
    885   // disappointment. Remember to check fclose(3)'s return value, kids!
    886   ASSERT_NE(nullptr, fp = tmpfile());
    887   ASSERT_EQ(4, fprintf(fp, "epic"));
    888   ASSERT_EQ(0, close(fileno(fp)));
    889   ASSERT_EQ(4, fprintf(fp, "fail"));
    890   ASSERT_EQ(-1, fclose(fp));
    891 }
    892 
    893 TEST(STDIO_TEST, popen) {
    894   FILE* fp = popen("cat /proc/version", "r");
    895   ASSERT_TRUE(fp != NULL);
    896 
    897   char buf[16];
    898   char* s = fgets(buf, sizeof(buf), fp);
    899   buf[13] = '\0';
    900   ASSERT_STREQ("Linux version", s);
    901 
    902   ASSERT_EQ(0, pclose(fp));
    903 }
    904 
    905 TEST(STDIO_TEST, getc) {
    906   FILE* fp = fopen("/proc/version", "r");
    907   ASSERT_TRUE(fp != NULL);
    908   ASSERT_EQ('L', getc(fp));
    909   ASSERT_EQ('i', getc(fp));
    910   ASSERT_EQ('n', getc(fp));
    911   ASSERT_EQ('u', getc(fp));
    912   ASSERT_EQ('x', getc(fp));
    913   fclose(fp);
    914 }
    915 
    916 TEST(STDIO_TEST, putc) {
    917   FILE* fp = fopen("/proc/version", "r");
    918   ASSERT_TRUE(fp != NULL);
    919   ASSERT_EQ(EOF, putc('x', fp));
    920   fclose(fp);
    921 }
    922 
    923 TEST(STDIO_TEST, sscanf_swscanf) {
    924   struct stuff {
    925     char s1[123];
    926     int i1, i2;
    927     char cs1[3];
    928     char s2[3];
    929     char c1;
    930     double d1;
    931     float f1;
    932     char s3[123];
    933 
    934     void Check() {
    935       EXPECT_STREQ("hello", s1);
    936       EXPECT_EQ(123, i1);
    937       EXPECT_EQ(456, i2);
    938       EXPECT_EQ('a', cs1[0]);
    939       EXPECT_EQ('b', cs1[1]);
    940       EXPECT_EQ('x', cs1[2]); // No terminating NUL.
    941       EXPECT_STREQ("AB", s2); // Terminating NUL.
    942       EXPECT_EQ('!', c1);
    943       EXPECT_DOUBLE_EQ(1.23, d1);
    944       EXPECT_FLOAT_EQ(9.0f, f1);
    945       EXPECT_STREQ("world", s3);
    946     }
    947   } s;
    948 
    949   memset(&s, 'x', sizeof(s));
    950   ASSERT_EQ(9, sscanf("  hello 123 456abAB! 1.23 0x1.2p3 world",
    951                       "%s %i%i%2c%[A-Z]%c %lf %f %s",
    952                       s.s1, &s.i1, &s.i2, s.cs1, s.s2, &s.c1, &s.d1, &s.f1, s.s3));
    953   s.Check();
    954 
    955   memset(&s, 'x', sizeof(s));
    956   ASSERT_EQ(9, swscanf(L"  hello 123 456abAB! 1.23 0x1.2p3 world",
    957                        L"%s %i%i%2c%[A-Z]%c %lf %f %s",
    958                        s.s1, &s.i1, &s.i2, s.cs1, s.s2, &s.c1, &s.d1, &s.f1, s.s3));
    959   s.Check();
    960 }
    961 
    962 template <typename T>
    963 static void CheckScanf(int sscanf_fn(const T*, const T*, ...),
    964                        const T* input, const T* fmt,
    965                        int expected_count, const char* expected_string) {
    966   char buf[256] = {};
    967   ASSERT_EQ(expected_count, sscanf_fn(input, fmt, &buf)) << fmt;
    968   ASSERT_STREQ(expected_string, buf) << fmt;
    969 }
    970 
    971 TEST(STDIO_TEST, sscanf_ccl) {
    972   // `abc` is just those characters.
    973   CheckScanf(sscanf, "abcd", "%[abc]", 1, "abc");
    974   // `a-c` is the range 'a' .. 'c'.
    975   CheckScanf(sscanf, "abcd", "%[a-c]", 1, "abc");
    976   CheckScanf(sscanf, "-d", "%[a-c]", 0, "");
    977   CheckScanf(sscanf, "ac-bAd", "%[a--c]", 1, "ac-bA");
    978   // `a-c-e` is equivalent to `a-e`.
    979   CheckScanf(sscanf, "abcdefg", "%[a-c-e]", 1, "abcde");
    980   // `e-a` is equivalent to `ae-` (because 'e' > 'a').
    981   CheckScanf(sscanf, "-a-e-b", "%[e-a]", 1, "-a-e-");
    982   // An initial '^' negates the set.
    983   CheckScanf(sscanf, "abcde", "%[^d]", 1, "abc");
    984   CheckScanf(sscanf, "abcdefgh", "%[^c-d]", 1, "ab");
    985   CheckScanf(sscanf, "hgfedcba", "%[^c-d]", 1, "hgfe");
    986   // The first character may be ']' or '-' without being special.
    987   CheckScanf(sscanf, "[[]]x", "%[][]", 1, "[[]]");
    988   CheckScanf(sscanf, "-a-x", "%[-a]", 1, "-a-");
    989   // The last character may be '-' without being special.
    990   CheckScanf(sscanf, "-a-x", "%[a-]", 1, "-a-");
    991   // X--Y is [X--] + Y, not [X--] + [--Y] (a bug in my initial implementation).
    992   CheckScanf(sscanf, "+,-/.", "%[+--/]", 1, "+,-/");
    993 }
    994 
    995 TEST(STDIO_TEST, swscanf_ccl) {
    996   // `abc` is just those characters.
    997   CheckScanf(swscanf, L"abcd", L"%[abc]", 1, "abc");
    998   // `a-c` is the range 'a' .. 'c'.
    999   CheckScanf(swscanf, L"abcd", L"%[a-c]", 1, "abc");
   1000   CheckScanf(swscanf, L"-d", L"%[a-c]", 0, "");
   1001   CheckScanf(swscanf, L"ac-bAd", L"%[a--c]", 1, "ac-bA");
   1002   // `a-c-e` is equivalent to `a-e`.
   1003   CheckScanf(swscanf, L"abcdefg", L"%[a-c-e]", 1, "abcde");
   1004   // `e-a` is equivalent to `ae-` (because 'e' > 'a').
   1005   CheckScanf(swscanf, L"-a-e-b", L"%[e-a]", 1, "-a-e-");
   1006   // An initial '^' negates the set.
   1007   CheckScanf(swscanf, L"abcde", L"%[^d]", 1, "abc");
   1008   CheckScanf(swscanf, L"abcdefgh", L"%[^c-d]", 1, "ab");
   1009   CheckScanf(swscanf, L"hgfedcba", L"%[^c-d]", 1, "hgfe");
   1010   // The first character may be ']' or '-' without being special.
   1011   CheckScanf(swscanf, L"[[]]x", L"%[][]", 1, "[[]]");
   1012   CheckScanf(swscanf, L"-a-x", L"%[-a]", 1, "-a-");
   1013   // The last character may be '-' without being special.
   1014   CheckScanf(swscanf, L"-a-x", L"%[a-]", 1, "-a-");
   1015   // X--Y is [X--] + Y, not [X--] + [--Y] (a bug in my initial implementation).
   1016   CheckScanf(swscanf, L"+,-/.", L"%[+--/]", 1, "+,-/");
   1017 }
   1018 
   1019 template <typename T1, typename T2>
   1020 static void CheckScanfM(int sscanf_fn(const T1*, const T1*, ...),
   1021                         const T1* input, const T1* fmt,
   1022                         int expected_count, const T2* expected_string) {
   1023   T2* result = nullptr;
   1024   ASSERT_EQ(expected_count, sscanf_fn(input, fmt, &result)) << fmt;
   1025   if (expected_string == nullptr) {
   1026     ASSERT_EQ(nullptr, result);
   1027   } else {
   1028     ASSERT_STREQ(expected_string, result) << fmt;
   1029   }
   1030   free(result);
   1031 }
   1032 
   1033 TEST(STDIO_TEST, sscanf_mc) {
   1034   char* p1 = nullptr;
   1035   char* p2 = nullptr;
   1036   ASSERT_EQ(2, sscanf("hello", "%mc%mc", &p1, &p2));
   1037   ASSERT_EQ('h', *p1);
   1038   ASSERT_EQ('e', *p2);
   1039   free(p1);
   1040   free(p2);
   1041 
   1042   p1 = nullptr;
   1043   ASSERT_EQ(1, sscanf("hello", "%4mc", &p1));
   1044   ASSERT_EQ('h', p1[0]);
   1045   ASSERT_EQ('e', p1[1]);
   1046   ASSERT_EQ('l', p1[2]);
   1047   ASSERT_EQ('l', p1[3]);
   1048   free(p1);
   1049 
   1050   p1 = nullptr;
   1051   ASSERT_EQ(1, sscanf("hello world", "%30mc", &p1));
   1052   ASSERT_EQ('h', p1[0]);
   1053   ASSERT_EQ('e', p1[1]);
   1054   ASSERT_EQ('l', p1[2]);
   1055   ASSERT_EQ('l', p1[3]);
   1056   ASSERT_EQ('o', p1[4]);
   1057   free(p1);
   1058 }
   1059 
   1060 
   1061 TEST(STDIO_TEST, sscanf_mlc) {
   1062   // This is so useless that clang doesn't even believe it exists...
   1063 #pragma clang diagnostic push
   1064 #pragma clang diagnostic ignored "-Wformat-invalid-specifier"
   1065 #pragma clang diagnostic ignored "-Wformat-extra-args"
   1066 
   1067   wchar_t* p1 = nullptr;
   1068   wchar_t* p2 = nullptr;
   1069   ASSERT_EQ(2, sscanf("hello", "%mlc%mlc", &p1, &p2));
   1070   ASSERT_EQ(L'h', *p1);
   1071   ASSERT_EQ(L'e', *p2);
   1072   free(p1);
   1073   free(p2);
   1074 
   1075   p1 = nullptr;
   1076   ASSERT_EQ(1, sscanf("hello", "%4mlc", &p1));
   1077   ASSERT_EQ(L'h', p1[0]);
   1078   ASSERT_EQ(L'e', p1[1]);
   1079   ASSERT_EQ(L'l', p1[2]);
   1080   ASSERT_EQ(L'l', p1[3]);
   1081   free(p1);
   1082 
   1083   p1 = nullptr;
   1084   ASSERT_EQ(1, sscanf("hello world", "%30mlc", &p1));
   1085   ASSERT_EQ(L'h', p1[0]);
   1086   ASSERT_EQ(L'e', p1[1]);
   1087   ASSERT_EQ(L'l', p1[2]);
   1088   ASSERT_EQ(L'l', p1[3]);
   1089   ASSERT_EQ(L'o', p1[4]);
   1090   free(p1);
   1091 #pragma clang diagnostic pop
   1092 }
   1093 
   1094 
   1095 TEST(STDIO_TEST, sscanf_ms) {
   1096   CheckScanfM(sscanf, "hello", "%ms", 1, "hello");
   1097   CheckScanfM(sscanf, "hello", "%4ms", 1, "hell");
   1098   CheckScanfM(sscanf, "hello world", "%30ms", 1, "hello");
   1099 }
   1100 
   1101 TEST(STDIO_TEST, sscanf_mls) {
   1102   CheckScanfM(sscanf, "hello", "%mls", 1, L"hello");
   1103   CheckScanfM(sscanf, "hello", "%4mls", 1, L"hell");
   1104   CheckScanfM(sscanf, "hello world", "%30mls", 1, L"hello");
   1105 }
   1106 
   1107 TEST(STDIO_TEST, sscanf_m_ccl) {
   1108   CheckScanfM(sscanf, "hello", "%m[a-z]", 1, "hello");
   1109   CheckScanfM(sscanf, "hello", "%4m[a-z]", 1, "hell");
   1110   CheckScanfM(sscanf, "hello world", "%30m[a-z]", 1, "hello");
   1111 }
   1112 
   1113 TEST(STDIO_TEST, sscanf_ml_ccl) {
   1114   CheckScanfM(sscanf, "hello", "%ml[a-z]", 1, L"hello");
   1115   CheckScanfM(sscanf, "hello", "%4ml[a-z]", 1, L"hell");
   1116   CheckScanfM(sscanf, "hello world", "%30ml[a-z]", 1, L"hello");
   1117 }
   1118 
   1119 TEST(STDIO_TEST, sscanf_ls) {
   1120   wchar_t w[32] = {};
   1121   ASSERT_EQ(1, sscanf("hello world", "%ls", w));
   1122   ASSERT_EQ(L"hello", std::wstring(w));
   1123 }
   1124 
   1125 TEST(STDIO_TEST, sscanf_ls_suppress) {
   1126   ASSERT_EQ(0, sscanf("hello world", "%*ls %*ls"));
   1127 }
   1128 
   1129 TEST(STDIO_TEST, sscanf_ls_n) {
   1130   setlocale(LC_ALL, "C.UTF-8");
   1131   wchar_t w[32] = {};
   1132   int pos = 0;
   1133   ASSERT_EQ(1, sscanf("\xc4\x80", "%ls%n", w, &pos));
   1134   ASSERT_EQ(static_cast<wchar_t>(256), w[0]);
   1135   ASSERT_EQ(2, pos);
   1136 }
   1137 
   1138 TEST(STDIO_TEST, sscanf_ls_realloc) {
   1139   // This is so useless that clang doesn't even believe it exists...
   1140 #pragma clang diagnostic push
   1141 #pragma clang diagnostic ignored "-Wformat-invalid-specifier"
   1142 #pragma clang diagnostic ignored "-Wformat-extra-args"
   1143   wchar_t* p1 = nullptr;
   1144   wchar_t* p2 = nullptr;
   1145   ASSERT_EQ(2, sscanf("1234567890123456789012345678901234567890 world", "%mls %mls", &p1, &p2));
   1146   ASSERT_EQ(L"1234567890123456789012345678901234567890", std::wstring(p1));
   1147   ASSERT_EQ(L"world", std::wstring(p2));
   1148 #pragma clang diagnostic pop
   1149 }
   1150 
   1151 // https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=202240
   1152 TEST(STDIO_TEST, scanf_wscanf_EOF) {
   1153   EXPECT_EQ(0, sscanf("b", "ab"));
   1154   EXPECT_EQ(EOF, sscanf("", "a"));
   1155   EXPECT_EQ(0, swscanf(L"b", L"ab"));
   1156   EXPECT_EQ(EOF, swscanf(L"", L"a"));
   1157 }
   1158 
   1159 TEST(STDIO_TEST, scanf_invalid_UTF8) {
   1160 #if 0 // TODO: more tests invented during code review; no regressions, so fix later.
   1161   char buf[BUFSIZ];
   1162   wchar_t wbuf[BUFSIZ];
   1163 
   1164   memset(buf, 0, sizeof(buf));
   1165   memset(wbuf, 0, sizeof(wbuf));
   1166   EXPECT_EQ(0, sscanf("\xc0" " foo", "%ls %s", wbuf, buf));
   1167 #endif
   1168 }
   1169 
   1170 TEST(STDIO_TEST, scanf_no_match_no_termination) {
   1171   char buf[4] = "x";
   1172   EXPECT_EQ(0, sscanf("d", "%[abc]", buf));
   1173   EXPECT_EQ('x', buf[0]);
   1174   EXPECT_EQ(0, swscanf(L"d", L"%[abc]", buf));
   1175   EXPECT_EQ('x', buf[0]);
   1176 
   1177   wchar_t wbuf[4] = L"x";
   1178   EXPECT_EQ(0, swscanf(L"d", L"%l[abc]", wbuf));
   1179   EXPECT_EQ(L'x', wbuf[0]);
   1180 
   1181   EXPECT_EQ(EOF, sscanf("", "%s", buf));
   1182   EXPECT_EQ('x', buf[0]);
   1183 
   1184   EXPECT_EQ(EOF, swscanf(L"", L"%ls", wbuf));
   1185   EXPECT_EQ(L'x', wbuf[0]);
   1186 }
   1187 
   1188 TEST(STDIO_TEST, scanf_wscanf_wide_character_class) {
   1189 #if 0 // TODO: more tests invented during code review; no regressions, so fix later.
   1190   wchar_t buf[BUFSIZ];
   1191 
   1192   // A wide character shouldn't match an ASCII-only class for scanf or wscanf.
   1193   memset(buf, 0, sizeof(buf));
   1194   EXPECT_EQ(1, sscanf("xyz", "%l[xy]", buf));
   1195   EXPECT_EQ(L"x"s, std::wstring(buf));
   1196   memset(buf, 0, sizeof(buf));
   1197   EXPECT_EQ(1, swscanf(L"xyz", L"%l[xy]", buf));
   1198   EXPECT_EQ(L"x"s, std::wstring(buf));
   1199 
   1200   // Even if scanf has wide characters in a class, they won't match...
   1201   // TODO: is that a bug?
   1202   memset(buf, 0, sizeof(buf));
   1203   EXPECT_EQ(1, sscanf("xyz", "%l[xy]", buf));
   1204   EXPECT_EQ(L"x"s, std::wstring(buf));
   1205   // ...unless you use wscanf.
   1206   memset(buf, 0, sizeof(buf));
   1207   EXPECT_EQ(1, swscanf(L"xyz", L"%l[xy]", buf));
   1208   EXPECT_EQ(L"xy"s, std::wstring(buf));
   1209 
   1210   // Negation only covers ASCII for scanf...
   1211   memset(buf, 0, sizeof(buf));
   1212   EXPECT_EQ(1, sscanf("xyz", "%l[^ab]", buf));
   1213   EXPECT_EQ(L"x"s, std::wstring(buf));
   1214   // ...but covers wide characters for wscanf.
   1215   memset(buf, 0, sizeof(buf));
   1216   EXPECT_EQ(1, swscanf(L"xyz", L"%l[^ab]", buf));
   1217   EXPECT_EQ(L"xyz"s, std::wstring(buf));
   1218 
   1219   // We already determined that non-ASCII characters are ignored in scanf classes.
   1220   memset(buf, 0, sizeof(buf));
   1221   EXPECT_EQ(1, sscanf("x"
   1222                       "\xc4\x80" // Matches a byte from each wide char in the class.
   1223                       "\xc6\x82" // Neither byte is in the class.
   1224                       "yz",
   1225                       "%l[xy" "\xc5\x80" "\xc4\x81" "]", buf));
   1226   EXPECT_EQ(L"x", std::wstring(buf));
   1227   // bionic and glibc both behave badly for wscanf, so let's call it right for now...
   1228   memset(buf, 0, sizeof(buf));
   1229   EXPECT_EQ(1, swscanf(L"x"
   1230                        L"\xc4\x80"
   1231                        L"\xc6\x82"
   1232                        L"yz",
   1233                        L"%l[xy" L"\xc5\x80" L"\xc4\x81" L"]", buf));
   1234   // Note that this isn't L"x" --- although the *bytes* matched, they're
   1235   // not put back together as a wide character.
   1236   EXPECT_EQ(L"x" L"\xc4" L"\x80", std::wstring(buf));
   1237 #endif
   1238 }
   1239 
   1240 TEST(STDIO_TEST, cantwrite_EBADF) {
   1241   // If we open a file read-only...
   1242   FILE* fp = fopen("/proc/version", "r");
   1243 
   1244   // ...all attempts to write to that file should return failure.
   1245 
   1246   // They should also set errno to EBADF. This isn't POSIX, but it's traditional.
   1247   // glibc gets the wide-character functions wrong.
   1248 
   1249   errno = 0;
   1250   EXPECT_EQ(EOF, putc('x', fp));
   1251   EXPECT_EQ(EBADF, errno);
   1252 
   1253   errno = 0;
   1254   EXPECT_EQ(EOF, fprintf(fp, "hello"));
   1255   EXPECT_EQ(EBADF, errno);
   1256 
   1257   errno = 0;
   1258   EXPECT_EQ(EOF, fwprintf(fp, L"hello"));
   1259 #if defined(__BIONIC__)
   1260   EXPECT_EQ(EBADF, errno);
   1261 #endif
   1262 
   1263   errno = 0;
   1264   EXPECT_EQ(0U, fwrite("hello", 1, 2, fp));
   1265   EXPECT_EQ(EBADF, errno);
   1266 
   1267   errno = 0;
   1268   EXPECT_EQ(EOF, fputs("hello", fp));
   1269   EXPECT_EQ(EBADF, errno);
   1270 
   1271   errno = 0;
   1272   EXPECT_EQ(WEOF, fputwc(L'x', fp));
   1273 #if defined(__BIONIC__)
   1274   EXPECT_EQ(EBADF, errno);
   1275 #endif
   1276 }
   1277 
   1278 // Tests that we can only have a consistent and correct fpos_t when using
   1279 // f*pos functions (i.e. fpos doesn't get inside a multi byte character).
   1280 TEST(STDIO_TEST, consistent_fpos_t) {
   1281   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   1282   uselocale(LC_GLOBAL_LOCALE);
   1283 
   1284   FILE* fp = tmpfile();
   1285   ASSERT_TRUE(fp != NULL);
   1286 
   1287   wchar_t mb_one_bytes = L'h';
   1288   wchar_t mb_two_bytes = 0x00a2;
   1289   wchar_t mb_three_bytes = 0x20ac;
   1290   wchar_t mb_four_bytes = 0x24b62;
   1291 
   1292   // Write to file.
   1293   ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fputwc(mb_one_bytes, fp)));
   1294   ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp)));
   1295   ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp)));
   1296   ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp)));
   1297 
   1298   rewind(fp);
   1299 
   1300   // Record each character position.
   1301   fpos_t pos1;
   1302   fpos_t pos2;
   1303   fpos_t pos3;
   1304   fpos_t pos4;
   1305   fpos_t pos5;
   1306   EXPECT_EQ(0, fgetpos(fp, &pos1));
   1307   ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp)));
   1308   EXPECT_EQ(0, fgetpos(fp, &pos2));
   1309   ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp)));
   1310   EXPECT_EQ(0, fgetpos(fp, &pos3));
   1311   ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp)));
   1312   EXPECT_EQ(0, fgetpos(fp, &pos4));
   1313   ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp)));
   1314   EXPECT_EQ(0, fgetpos(fp, &pos5));
   1315 
   1316 #if defined(__BIONIC__)
   1317   // Bionic's fpos_t is just an alias for off_t. This is inherited from OpenBSD
   1318   // upstream. Glibc differs by storing the mbstate_t inside its fpos_t. In
   1319   // Bionic (and upstream OpenBSD) the mbstate_t is stored inside the FILE
   1320   // structure.
   1321   ASSERT_EQ(0, static_cast<off_t>(pos1));
   1322   ASSERT_EQ(1, static_cast<off_t>(pos2));
   1323   ASSERT_EQ(3, static_cast<off_t>(pos3));
   1324   ASSERT_EQ(6, static_cast<off_t>(pos4));
   1325   ASSERT_EQ(10, static_cast<off_t>(pos5));
   1326 #endif
   1327 
   1328   // Exercise back and forth movements of the position.
   1329   ASSERT_EQ(0, fsetpos(fp, &pos2));
   1330   ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp)));
   1331   ASSERT_EQ(0, fsetpos(fp, &pos1));
   1332   ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp)));
   1333   ASSERT_EQ(0, fsetpos(fp, &pos4));
   1334   ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp)));
   1335   ASSERT_EQ(0, fsetpos(fp, &pos3));
   1336   ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp)));
   1337   ASSERT_EQ(0, fsetpos(fp, &pos5));
   1338   ASSERT_EQ(WEOF, fgetwc(fp));
   1339 
   1340   fclose(fp);
   1341 }
   1342 
   1343 // Exercise the interaction between fpos and seek.
   1344 TEST(STDIO_TEST, fpos_t_and_seek) {
   1345   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   1346   uselocale(LC_GLOBAL_LOCALE);
   1347 
   1348   // In glibc-2.16 fseek doesn't work properly in wide mode
   1349   // (https://sourceware.org/bugzilla/show_bug.cgi?id=14543). One workaround is
   1350   // to close and re-open the file. We do it in order to make the test pass
   1351   // with all glibcs.
   1352 
   1353   TemporaryFile tf;
   1354   FILE* fp = fdopen(tf.fd, "w+");
   1355   ASSERT_TRUE(fp != NULL);
   1356 
   1357   wchar_t mb_two_bytes = 0x00a2;
   1358   wchar_t mb_three_bytes = 0x20ac;
   1359   wchar_t mb_four_bytes = 0x24b62;
   1360 
   1361   // Write to file.
   1362   ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp)));
   1363   ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp)));
   1364   ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp)));
   1365 
   1366   fflush(fp);
   1367   fclose(fp);
   1368 
   1369   fp = fopen(tf.filename, "r");
   1370   ASSERT_TRUE(fp != NULL);
   1371 
   1372   // Store a valid position.
   1373   fpos_t mb_two_bytes_pos;
   1374   ASSERT_EQ(0, fgetpos(fp, &mb_two_bytes_pos));
   1375 
   1376   // Move inside mb_four_bytes with fseek.
   1377   long offset_inside_mb = 6;
   1378   ASSERT_EQ(0, fseek(fp, offset_inside_mb, SEEK_SET));
   1379 
   1380   // Store the "inside multi byte" position.
   1381   fpos_t pos_inside_mb;
   1382   ASSERT_EQ(0, fgetpos(fp, &pos_inside_mb));
   1383 #if defined(__BIONIC__)
   1384   ASSERT_EQ(offset_inside_mb, static_cast<off_t>(pos_inside_mb));
   1385 #endif
   1386 
   1387   // Reading from within a byte should produce an error.
   1388   ASSERT_EQ(WEOF, fgetwc(fp));
   1389   ASSERT_EQ(EILSEQ, errno);
   1390 
   1391   // Reverting to a valid position should work.
   1392   ASSERT_EQ(0, fsetpos(fp, &mb_two_bytes_pos));
   1393   ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp)));
   1394 
   1395   // Moving withing a multi byte with fsetpos should work but reading should
   1396   // produce an error.
   1397   ASSERT_EQ(0, fsetpos(fp, &pos_inside_mb));
   1398   ASSERT_EQ(WEOF, fgetwc(fp));
   1399   ASSERT_EQ(EILSEQ, errno);
   1400 
   1401   ASSERT_EQ(0, fclose(fp));
   1402 }
   1403 
   1404 TEST(STDIO_TEST, fmemopen) {
   1405   char buf[16];
   1406   memset(buf, 0, sizeof(buf));
   1407   FILE* fp = fmemopen(buf, sizeof(buf), "r+");
   1408   ASSERT_EQ('<', fputc('<', fp));
   1409   ASSERT_NE(EOF, fputs("abc>\n", fp));
   1410   fflush(fp);
   1411 
   1412   // We wrote to the buffer...
   1413   ASSERT_STREQ("<abc>\n", buf);
   1414 
   1415   // And can read back from the file.
   1416   AssertFileIs(fp, "<abc>\n", true);
   1417   ASSERT_EQ(0, fclose(fp));
   1418 }
   1419 
   1420 TEST(STDIO_TEST, fmemopen_nullptr) {
   1421   FILE* fp = fmemopen(nullptr, 128, "r+");
   1422   ASSERT_NE(EOF, fputs("xyz\n", fp));
   1423 
   1424   AssertFileIs(fp, "xyz\n", true);
   1425   ASSERT_EQ(0, fclose(fp));
   1426 }
   1427 
   1428 TEST(STDIO_TEST, fmemopen_trailing_NUL_byte) {
   1429   FILE* fp;
   1430   char buf[8];
   1431 
   1432   // POSIX: "When a stream open for writing is flushed or closed, a null byte
   1433   // shall be written at the current position or at the end of the buffer,
   1434   // depending on the size of the contents."
   1435   memset(buf, 'x', sizeof(buf));
   1436   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w"));
   1437   // Even with nothing written (and not in truncate mode), we'll flush a NUL...
   1438   ASSERT_EQ(0, fflush(fp));
   1439   EXPECT_EQ("\0xxxxxxx"s, std::string(buf, buf + sizeof(buf)));
   1440   // Now write and check that the NUL moves along with our writes...
   1441   ASSERT_NE(EOF, fputs("hello", fp));
   1442   ASSERT_EQ(0, fflush(fp));
   1443   EXPECT_EQ("hello\0xx"s, std::string(buf, buf + sizeof(buf)));
   1444   ASSERT_NE(EOF, fputs("wo", fp));
   1445   ASSERT_EQ(0, fflush(fp));
   1446   EXPECT_EQ("hellowo\0"s, std::string(buf, buf + sizeof(buf)));
   1447   ASSERT_EQ(0, fclose(fp));
   1448 
   1449   // "If a stream open for update is flushed or closed and the last write has
   1450   // advanced the current buffer size, a null byte shall be written at the end
   1451   // of the buffer if it fits."
   1452   memset(buf, 'x', sizeof(buf));
   1453   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "r+"));
   1454   // Nothing written yet, so no advance...
   1455   ASSERT_EQ(0, fflush(fp));
   1456   EXPECT_EQ("xxxxxxxx"s, std::string(buf, buf + sizeof(buf)));
   1457   ASSERT_NE(EOF, fputs("hello", fp));
   1458   ASSERT_EQ(0, fclose(fp));
   1459 }
   1460 
   1461 TEST(STDIO_TEST, fmemopen_size) {
   1462   FILE* fp;
   1463   char buf[16];
   1464   memset(buf, 'x', sizeof(buf));
   1465 
   1466   // POSIX: "The stream shall also maintain the size of the current buffer
   1467   // contents; use of fseek() or fseeko() on the stream with SEEK_END shall
   1468   // seek relative to this size."
   1469 
   1470   // "For modes r and r+ the size shall be set to the value given by the size
   1471   // argument."
   1472   ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "r"));
   1473   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1474   EXPECT_EQ(16, ftell(fp));
   1475   EXPECT_EQ(16, ftello(fp));
   1476   ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
   1477   EXPECT_EQ(16, ftell(fp));
   1478   EXPECT_EQ(16, ftello(fp));
   1479   ASSERT_EQ(0, fclose(fp));
   1480   ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "r+"));
   1481   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1482   EXPECT_EQ(16, ftell(fp));
   1483   EXPECT_EQ(16, ftello(fp));
   1484   ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
   1485   EXPECT_EQ(16, ftell(fp));
   1486   EXPECT_EQ(16, ftello(fp));
   1487   ASSERT_EQ(0, fclose(fp));
   1488 
   1489   // "For modes w and w+ the initial size shall be zero..."
   1490   ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "w"));
   1491   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1492   EXPECT_EQ(0, ftell(fp));
   1493   EXPECT_EQ(0, ftello(fp));
   1494   ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
   1495   EXPECT_EQ(0, ftell(fp));
   1496   EXPECT_EQ(0, ftello(fp));
   1497   ASSERT_EQ(0, fclose(fp));
   1498   ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "w+"));
   1499   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1500   EXPECT_EQ(0, ftell(fp));
   1501   EXPECT_EQ(0, ftello(fp));
   1502   ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
   1503   EXPECT_EQ(0, ftell(fp));
   1504   EXPECT_EQ(0, ftello(fp));
   1505   ASSERT_EQ(0, fclose(fp));
   1506 
   1507   // "...and for modes a and a+ the initial size shall be:
   1508   // 1. Zero, if buf is a null pointer
   1509   ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "a"));
   1510   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1511   EXPECT_EQ(0, ftell(fp));
   1512   EXPECT_EQ(0, ftello(fp));
   1513   ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
   1514   EXPECT_EQ(0, ftell(fp));
   1515   EXPECT_EQ(0, ftello(fp));
   1516   ASSERT_EQ(0, fclose(fp));
   1517   ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "a+"));
   1518   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1519   EXPECT_EQ(0, ftell(fp));
   1520   EXPECT_EQ(0, ftello(fp));
   1521   ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
   1522   EXPECT_EQ(0, ftell(fp));
   1523   EXPECT_EQ(0, ftello(fp));
   1524   ASSERT_EQ(0, fclose(fp));
   1525 
   1526   // 2. The position of the first null byte in the buffer, if one is found
   1527   memset(buf, 'x', sizeof(buf));
   1528   buf[3] = '\0';
   1529   ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "a"));
   1530   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1531   EXPECT_EQ(3, ftell(fp));
   1532   EXPECT_EQ(3, ftello(fp));
   1533   ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
   1534   EXPECT_EQ(3, ftell(fp));
   1535   EXPECT_EQ(3, ftello(fp));
   1536   ASSERT_EQ(0, fclose(fp));
   1537   memset(buf, 'x', sizeof(buf));
   1538   buf[3] = '\0';
   1539   ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "a+"));
   1540   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1541   EXPECT_EQ(3, ftell(fp));
   1542   EXPECT_EQ(3, ftello(fp));
   1543   ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
   1544   EXPECT_EQ(3, ftell(fp));
   1545   EXPECT_EQ(3, ftello(fp));
   1546   ASSERT_EQ(0, fclose(fp));
   1547 
   1548   // 3. The value of the size argument, if buf is not a null pointer and no
   1549   // null byte is found.
   1550   memset(buf, 'x', sizeof(buf));
   1551   ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "a"));
   1552   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1553   EXPECT_EQ(16, ftell(fp));
   1554   EXPECT_EQ(16, ftello(fp));
   1555   ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
   1556   EXPECT_EQ(16, ftell(fp));
   1557   EXPECT_EQ(16, ftello(fp));
   1558   ASSERT_EQ(0, fclose(fp));
   1559   memset(buf, 'x', sizeof(buf));
   1560   ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "a+"));
   1561   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1562   EXPECT_EQ(16, ftell(fp));
   1563   EXPECT_EQ(16, ftello(fp));
   1564   ASSERT_EQ(0, fseeko(fp, 0, SEEK_END));
   1565   EXPECT_EQ(16, ftell(fp));
   1566   EXPECT_EQ(16, ftello(fp));
   1567   ASSERT_EQ(0, fclose(fp));
   1568 }
   1569 
   1570 TEST(STDIO_TEST, fmemopen_SEEK_END) {
   1571   // fseek SEEK_END is relative to the current string length, not the buffer size.
   1572   FILE* fp;
   1573   char buf[8];
   1574   memset(buf, 'x', sizeof(buf));
   1575   strcpy(buf, "str");
   1576   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w+"));
   1577   ASSERT_NE(EOF, fputs("string", fp));
   1578   EXPECT_EQ(0, fseek(fp, 0, SEEK_END));
   1579   EXPECT_EQ(static_cast<long>(strlen("string")), ftell(fp));
   1580   EXPECT_EQ(static_cast<off_t>(strlen("string")), ftello(fp));
   1581   EXPECT_EQ(0, fclose(fp));
   1582 
   1583   // glibc < 2.22 interpreted SEEK_END the wrong way round (subtracting rather
   1584   // than adding).
   1585   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w+"));
   1586   ASSERT_NE(EOF, fputs("54321", fp));
   1587   EXPECT_EQ(0, fseek(fp, -2, SEEK_END));
   1588   EXPECT_EQ('2', fgetc(fp));
   1589   EXPECT_EQ(0, fclose(fp));
   1590 }
   1591 
   1592 TEST(STDIO_TEST, fmemopen_seek_invalid) {
   1593   char buf[8];
   1594   memset(buf, 'x', sizeof(buf));
   1595   FILE* fp = fmemopen(buf, sizeof(buf), "w");
   1596   ASSERT_TRUE(fp != nullptr);
   1597 
   1598   // POSIX: "An attempt to seek ... to a negative position or to a position
   1599   // larger than the buffer size given in the size argument shall fail."
   1600   // (There's no mention of what errno should be set to, and glibc doesn't
   1601   // set errno in any of these cases.)
   1602   EXPECT_EQ(-1, fseek(fp, -2, SEEK_SET));
   1603   EXPECT_EQ(-1, fseeko(fp, -2, SEEK_SET));
   1604   EXPECT_EQ(-1, fseek(fp, sizeof(buf) + 1, SEEK_SET));
   1605   EXPECT_EQ(-1, fseeko(fp, sizeof(buf) + 1, SEEK_SET));
   1606 }
   1607 
   1608 TEST(STDIO_TEST, fmemopen_read_EOF) {
   1609   // POSIX: "A read operation on the stream shall not advance the current
   1610   // buffer position beyond the current buffer size."
   1611   char buf[8];
   1612   memset(buf, 'x', sizeof(buf));
   1613   FILE* fp = fmemopen(buf, sizeof(buf), "r");
   1614   ASSERT_TRUE(fp != nullptr);
   1615   char buf2[BUFSIZ];
   1616   ASSERT_EQ(8U, fread(buf2, 1, sizeof(buf2), fp));
   1617   // POSIX: "Reaching the buffer size in a read operation shall count as
   1618   // end-of-file.
   1619   ASSERT_TRUE(feof(fp));
   1620   ASSERT_EQ(EOF, fgetc(fp));
   1621   ASSERT_EQ(0, fclose(fp));
   1622 }
   1623 
   1624 TEST(STDIO_TEST, fmemopen_read_null_bytes) {
   1625   // POSIX: "Null bytes in the buffer shall have no special meaning for reads."
   1626   char buf[] = "h\0e\0l\0l\0o";
   1627   FILE* fp = fmemopen(buf, sizeof(buf), "r");
   1628   ASSERT_TRUE(fp != nullptr);
   1629   ASSERT_EQ('h', fgetc(fp));
   1630   ASSERT_EQ(0, fgetc(fp));
   1631   ASSERT_EQ('e', fgetc(fp));
   1632   ASSERT_EQ(0, fgetc(fp));
   1633   ASSERT_EQ('l', fgetc(fp));
   1634   ASSERT_EQ(0, fgetc(fp));
   1635   // POSIX: "The read operation shall start at the current buffer position of
   1636   // the stream."
   1637   char buf2[8];
   1638   memset(buf2, 'x', sizeof(buf2));
   1639   ASSERT_EQ(4U, fread(buf2, 1, sizeof(buf2), fp));
   1640   ASSERT_EQ('l', buf2[0]);
   1641   ASSERT_EQ(0, buf2[1]);
   1642   ASSERT_EQ('o', buf2[2]);
   1643   ASSERT_EQ(0, buf2[3]);
   1644   for (size_t i = 4; i < sizeof(buf2); ++i) ASSERT_EQ('x', buf2[i]) << i;
   1645   ASSERT_TRUE(feof(fp));
   1646   ASSERT_EQ(0, fclose(fp));
   1647 }
   1648 
   1649 TEST(STDIO_TEST, fmemopen_write) {
   1650   FILE* fp;
   1651   char buf[8];
   1652 
   1653   // POSIX: "A write operation shall start either at the current position of
   1654   // the stream (if mode has not specified 'a' as the first character)..."
   1655   memset(buf, 'x', sizeof(buf));
   1656   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "r+"));
   1657   setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
   1658   ASSERT_EQ(0, fseek(fp, 2, SEEK_SET));
   1659   ASSERT_EQ(' ', fputc(' ', fp));
   1660   EXPECT_EQ("xx xxxxx", std::string(buf, buf + sizeof(buf)));
   1661   ASSERT_EQ(0, fclose(fp));
   1662 
   1663   // "...or at the current size of the stream (if mode had 'a' as the first
   1664   // character)." (See the fmemopen_size test for what "size" means, but for
   1665   // mode "a", it's the first NUL byte.)
   1666   memset(buf, 'x', sizeof(buf));
   1667   buf[3] = '\0';
   1668   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a+"));
   1669   setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
   1670   ASSERT_EQ(' ', fputc(' ', fp));
   1671   EXPECT_EQ("xxx \0xxx"s, std::string(buf, buf + sizeof(buf)));
   1672   ASSERT_EQ(0, fclose(fp));
   1673 
   1674   // "If the current position at the end of the write is larger than the
   1675   // current buffer size, the current buffer size shall be set to the current
   1676   // position." (See the fmemopen_size test for what "size" means, but to
   1677   // query it we SEEK_END with offset 0, and then ftell.)
   1678   memset(buf, 'x', sizeof(buf));
   1679   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w+"));
   1680   setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
   1681   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1682   EXPECT_EQ(0, ftell(fp));
   1683   ASSERT_EQ(' ', fputc(' ', fp));
   1684   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1685   EXPECT_EQ(1, ftell(fp));
   1686   ASSERT_NE(EOF, fputs("123", fp));
   1687   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   1688   EXPECT_EQ(4, ftell(fp));
   1689   EXPECT_EQ(" 123\0xxx"s, std::string(buf, buf + sizeof(buf)));
   1690   ASSERT_EQ(0, fclose(fp));
   1691 }
   1692 
   1693 TEST(STDIO_TEST, fmemopen_write_EOF) {
   1694   // POSIX: "A write operation on the stream shall not advance the current
   1695   // buffer size beyond the size given in the size argument."
   1696   FILE* fp;
   1697 
   1698   // Scalar writes...
   1699   ASSERT_NE(nullptr, fp = fmemopen(nullptr, 4, "w"));
   1700   setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
   1701   ASSERT_EQ('x', fputc('x', fp));
   1702   ASSERT_EQ('x', fputc('x', fp));
   1703   ASSERT_EQ('x', fputc('x', fp));
   1704   ASSERT_EQ(EOF, fputc('x', fp)); // Only 3 fit because of the implicit NUL.
   1705   ASSERT_EQ(0, fclose(fp));
   1706 
   1707   // Vector writes...
   1708   ASSERT_NE(nullptr, fp = fmemopen(nullptr, 4, "w"));
   1709   setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
   1710   ASSERT_EQ(3U, fwrite("xxxx", 1, 4, fp));
   1711   ASSERT_EQ(0, fclose(fp));
   1712 }
   1713 
   1714 TEST(STDIO_TEST, fmemopen_initial_position) {
   1715   // POSIX: "The ... current position in the buffer ... shall be initially
   1716   // set to either the beginning of the buffer (for r and w modes) ..."
   1717   char buf[] = "hello\0world";
   1718   FILE* fp;
   1719   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "r"));
   1720   EXPECT_EQ(0L, ftell(fp));
   1721   EXPECT_EQ(0, fclose(fp));
   1722   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w"));
   1723   EXPECT_EQ(0L, ftell(fp));
   1724   EXPECT_EQ(0, fclose(fp));
   1725   buf[0] = 'h'; // (Undo the effects of the above.)
   1726 
   1727   // POSIX: "...or to the first null byte in the buffer (for a modes)."
   1728   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a"));
   1729   EXPECT_EQ(5L, ftell(fp));
   1730   EXPECT_EQ(0, fclose(fp));
   1731 
   1732   // POSIX: "If no null byte is found in append mode, the initial position
   1733   // shall be set to one byte after the end of the buffer."
   1734   memset(buf, 'x', sizeof(buf));
   1735   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a"));
   1736   EXPECT_EQ(static_cast<long>(sizeof(buf)), ftell(fp));
   1737   EXPECT_EQ(0, fclose(fp));
   1738 }
   1739 
   1740 TEST(STDIO_TEST, fmemopen_initial_position_allocated) {
   1741   // POSIX: "If buf is a null pointer, the initial position shall always be
   1742   // set to the beginning of the buffer."
   1743   FILE* fp = fmemopen(nullptr, 128, "a+");
   1744   ASSERT_TRUE(fp != nullptr);
   1745   EXPECT_EQ(0L, ftell(fp));
   1746   EXPECT_EQ(0L, fseek(fp, 0, SEEK_SET));
   1747   EXPECT_EQ(0, fclose(fp));
   1748 }
   1749 
   1750 TEST(STDIO_TEST, fmemopen_zero_length) {
   1751   // POSIX says it's up to the implementation whether or not you can have a
   1752   // zero-length buffer (but "A future version of this standard may require
   1753   // support of zero-length buffer streams explicitly"). BSD and glibc < 2.22
   1754   // agreed that you couldn't, but glibc >= 2.22 allows it for consistency.
   1755   FILE* fp;
   1756   char buf[16];
   1757   ASSERT_NE(nullptr, fp = fmemopen(buf, 0, "r+"));
   1758   ASSERT_EQ(EOF, fgetc(fp));
   1759   ASSERT_TRUE(feof(fp));
   1760   ASSERT_EQ(0, fclose(fp));
   1761   ASSERT_NE(nullptr, fp = fmemopen(nullptr, 0, "r+"));
   1762   ASSERT_EQ(EOF, fgetc(fp));
   1763   ASSERT_TRUE(feof(fp));
   1764   ASSERT_EQ(0, fclose(fp));
   1765 
   1766   ASSERT_NE(nullptr, fp = fmemopen(buf, 0, "w+"));
   1767   setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
   1768   ASSERT_EQ(EOF, fputc('x', fp));
   1769   ASSERT_EQ(0, fclose(fp));
   1770   ASSERT_NE(nullptr, fp = fmemopen(nullptr, 0, "w+"));
   1771   setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
   1772   ASSERT_EQ(EOF, fputc('x', fp));
   1773   ASSERT_EQ(0, fclose(fp));
   1774 }
   1775 
   1776 TEST(STDIO_TEST, fmemopen_write_only_allocated) {
   1777   // POSIX says fmemopen "may fail if the mode argument does not include a '+'".
   1778   // BSD fails, glibc doesn't. We side with the more lenient.
   1779   FILE* fp;
   1780   ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "r"));
   1781   ASSERT_EQ(0, fclose(fp));
   1782   ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "w"));
   1783   ASSERT_EQ(0, fclose(fp));
   1784 }
   1785 
   1786 TEST(STDIO_TEST, fmemopen_fileno) {
   1787   // There's no fd backing an fmemopen FILE*.
   1788   FILE* fp = fmemopen(nullptr, 16, "r");
   1789   ASSERT_TRUE(fp != nullptr);
   1790   errno = 0;
   1791   ASSERT_EQ(-1, fileno(fp));
   1792   ASSERT_EQ(EBADF, errno);
   1793   ASSERT_EQ(0, fclose(fp));
   1794 }
   1795 
   1796 TEST(STDIO_TEST, fmemopen_append_after_seek) {
   1797   // In BSD and glibc < 2.22, append mode didn't force writes to append if
   1798   // there had been an intervening seek.
   1799 
   1800   FILE* fp;
   1801   char buf[] = "hello\0world";
   1802   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a"));
   1803   setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
   1804   ASSERT_EQ(0, fseek(fp, 0, SEEK_SET));
   1805   ASSERT_NE(EOF, fputc('!', fp));
   1806   EXPECT_EQ("hello!\0orld\0"s, std::string(buf, buf + sizeof(buf)));
   1807   ASSERT_EQ(0, fclose(fp));
   1808 
   1809   memcpy(buf, "hello\0world", sizeof(buf));
   1810   ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a+"));
   1811   setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens.
   1812   ASSERT_EQ(0, fseek(fp, 0, SEEK_SET));
   1813   ASSERT_NE(EOF, fputc('!', fp));
   1814   EXPECT_EQ("hello!\0orld\0"s, std::string(buf, buf + sizeof(buf)));
   1815   ASSERT_EQ(0, fclose(fp));
   1816 }
   1817 
   1818 TEST(STDIO_TEST, open_memstream) {
   1819   char* p = nullptr;
   1820   size_t size = 0;
   1821   FILE* fp = open_memstream(&p, &size);
   1822   ASSERT_NE(EOF, fputs("hello, world!", fp));
   1823   fclose(fp);
   1824 
   1825   ASSERT_STREQ("hello, world!", p);
   1826   ASSERT_EQ(strlen("hello, world!"), size);
   1827   free(p);
   1828 }
   1829 
   1830 TEST(STDIO_TEST, open_memstream_EINVAL) {
   1831 #if defined(__BIONIC__)
   1832   char* p;
   1833   size_t size;
   1834 
   1835   // Invalid buffer.
   1836   errno = 0;
   1837   ASSERT_EQ(nullptr, open_memstream(nullptr, &size));
   1838   ASSERT_EQ(EINVAL, errno);
   1839 
   1840   // Invalid size.
   1841   errno = 0;
   1842   ASSERT_EQ(nullptr, open_memstream(&p, nullptr));
   1843   ASSERT_EQ(EINVAL, errno);
   1844 #else
   1845   GTEST_LOG_(INFO) << "This test does nothing on glibc.\n";
   1846 #endif
   1847 }
   1848 
   1849 TEST(STDIO_TEST, fdopen_CLOEXEC) {
   1850   int fd = open("/proc/version", O_RDONLY);
   1851   ASSERT_TRUE(fd != -1);
   1852 
   1853   // This fd doesn't have O_CLOEXEC...
   1854   AssertCloseOnExec(fd, false);
   1855 
   1856   FILE* fp = fdopen(fd, "re");
   1857   ASSERT_TRUE(fp != NULL);
   1858 
   1859   // ...but the new one does.
   1860   AssertCloseOnExec(fileno(fp), true);
   1861 
   1862   fclose(fp);
   1863   close(fd);
   1864 }
   1865 
   1866 TEST(STDIO_TEST, freopen_CLOEXEC) {
   1867   FILE* fp = fopen("/proc/version", "r");
   1868   ASSERT_TRUE(fp != NULL);
   1869 
   1870   // This FILE* doesn't have O_CLOEXEC...
   1871   AssertCloseOnExec(fileno(fp), false);
   1872 
   1873   fp = freopen("/proc/version", "re", fp);
   1874 
   1875   // ...but the new one does.
   1876   AssertCloseOnExec(fileno(fp), true);
   1877 
   1878   fclose(fp);
   1879 }
   1880 
   1881 TEST(STDIO_TEST, fopen64_freopen64) {
   1882   FILE* fp = fopen64("/proc/version", "r");
   1883   ASSERT_TRUE(fp != nullptr);
   1884   fp = freopen64("/proc/version", "re", fp);
   1885   ASSERT_TRUE(fp != nullptr);
   1886   fclose(fp);
   1887 }
   1888 
   1889 // https://code.google.com/p/android/issues/detail?id=81155
   1890 // http://b/18556607
   1891 TEST(STDIO_TEST, fread_unbuffered_pathological_performance) {
   1892   FILE* fp = fopen("/dev/zero", "r");
   1893   ASSERT_TRUE(fp != NULL);
   1894 
   1895   // Make this stream unbuffered.
   1896   setvbuf(fp, 0, _IONBF, 0);
   1897 
   1898   char buf[65*1024];
   1899   memset(buf, 0xff, sizeof(buf));
   1900 
   1901   time_t t0 = time(NULL);
   1902   for (size_t i = 0; i < 1024; ++i) {
   1903     ASSERT_EQ(1U, fread(buf, 64*1024, 1, fp));
   1904   }
   1905   time_t t1 = time(NULL);
   1906 
   1907   fclose(fp);
   1908 
   1909   // 1024 64KiB reads should have been very quick.
   1910   ASSERT_LE(t1 - t0, 1);
   1911 
   1912   for (size_t i = 0; i < 64*1024; ++i) {
   1913     ASSERT_EQ('\0', buf[i]);
   1914   }
   1915   for (size_t i = 64*1024; i < 65*1024; ++i) {
   1916     ASSERT_EQ('\xff', buf[i]);
   1917   }
   1918 }
   1919 
   1920 TEST(STDIO_TEST, fread_EOF) {
   1921   std::string digits("0123456789");
   1922   FILE* fp = fmemopen(&digits[0], digits.size(), "r");
   1923 
   1924   // Try to read too much, but little enough that it still fits in the FILE's internal buffer.
   1925   char buf1[4 * 4];
   1926   memset(buf1, 0, sizeof(buf1));
   1927   ASSERT_EQ(2U, fread(buf1, 4, 4, fp));
   1928   ASSERT_STREQ("0123456789", buf1);
   1929   ASSERT_TRUE(feof(fp));
   1930 
   1931   rewind(fp);
   1932 
   1933   // Try to read way too much so stdio tries to read more direct from the stream.
   1934   char buf2[4 * 4096];
   1935   memset(buf2, 0, sizeof(buf2));
   1936   ASSERT_EQ(2U, fread(buf2, 4, 4096, fp));
   1937   ASSERT_STREQ("0123456789", buf2);
   1938   ASSERT_TRUE(feof(fp));
   1939 
   1940   fclose(fp);
   1941 }
   1942 
   1943 static void test_fread_from_write_only_stream(size_t n) {
   1944   FILE* fp = fopen("/dev/null", "w");
   1945   std::vector<char> buf(n, 0);
   1946   errno = 0;
   1947   ASSERT_EQ(0U, fread(&buf[0], n, 1, fp));
   1948   ASSERT_EQ(EBADF, errno);
   1949   ASSERT_TRUE(ferror(fp));
   1950   ASSERT_FALSE(feof(fp));
   1951   fclose(fp);
   1952 }
   1953 
   1954 TEST(STDIO_TEST, fread_from_write_only_stream_slow_path) {
   1955   test_fread_from_write_only_stream(1);
   1956 }
   1957 
   1958 TEST(STDIO_TEST, fread_from_write_only_stream_fast_path) {
   1959   test_fread_from_write_only_stream(64*1024);
   1960 }
   1961 
   1962 static void test_fwrite_after_fread(size_t n) {
   1963   TemporaryFile tf;
   1964 
   1965   FILE* fp = fdopen(tf.fd, "w+");
   1966   ASSERT_EQ(1U, fwrite("1", 1, 1, fp));
   1967   fflush(fp);
   1968 
   1969   // We've flushed but not rewound, so there's nothing to read.
   1970   std::vector<char> buf(n, 0);
   1971   ASSERT_EQ(0U, fread(&buf[0], 1, buf.size(), fp));
   1972   ASSERT_TRUE(feof(fp));
   1973 
   1974   // But hitting EOF doesn't prevent us from writing...
   1975   errno = 0;
   1976   ASSERT_EQ(1U, fwrite("2", 1, 1, fp)) << strerror(errno);
   1977 
   1978   // And if we rewind, everything's there.
   1979   rewind(fp);
   1980   ASSERT_EQ(2U, fread(&buf[0], 1, buf.size(), fp));
   1981   ASSERT_EQ('1', buf[0]);
   1982   ASSERT_EQ('2', buf[1]);
   1983 
   1984   fclose(fp);
   1985 }
   1986 
   1987 TEST(STDIO_TEST, fwrite_after_fread_slow_path) {
   1988   test_fwrite_after_fread(16);
   1989 }
   1990 
   1991 TEST(STDIO_TEST, fwrite_after_fread_fast_path) {
   1992   test_fwrite_after_fread(64*1024);
   1993 }
   1994 
   1995 // http://b/19172514
   1996 TEST(STDIO_TEST, fread_after_fseek) {
   1997   TemporaryFile tf;
   1998 
   1999   FILE* fp = fopen(tf.filename, "w+");
   2000   ASSERT_TRUE(fp != nullptr);
   2001 
   2002   char file_data[12288];
   2003   for (size_t i = 0; i < 12288; i++) {
   2004     file_data[i] = i;
   2005   }
   2006   ASSERT_EQ(12288U, fwrite(file_data, 1, 12288, fp));
   2007   fclose(fp);
   2008 
   2009   fp = fopen(tf.filename, "r");
   2010   ASSERT_TRUE(fp != nullptr);
   2011 
   2012   char buffer[8192];
   2013   size_t cur_location = 0;
   2014   // Small read to populate internal buffer.
   2015   ASSERT_EQ(100U, fread(buffer, 1, 100, fp));
   2016   ASSERT_EQ(memcmp(file_data, buffer, 100), 0);
   2017 
   2018   cur_location = static_cast<size_t>(ftell(fp));
   2019   // Large read to force reading into the user supplied buffer and bypassing
   2020   // the internal buffer.
   2021   ASSERT_EQ(8192U, fread(buffer, 1, 8192, fp));
   2022   ASSERT_EQ(memcmp(file_data+cur_location, buffer, 8192), 0);
   2023 
   2024   // Small backwards seek to verify fseek does not reuse the internal buffer.
   2025   ASSERT_EQ(0, fseek(fp, -22, SEEK_CUR)) << strerror(errno);
   2026   cur_location = static_cast<size_t>(ftell(fp));
   2027   ASSERT_EQ(22U, fread(buffer, 1, 22, fp));
   2028   ASSERT_EQ(memcmp(file_data+cur_location, buffer, 22), 0);
   2029 
   2030   fclose(fp);
   2031 }
   2032 
   2033 // https://code.google.com/p/android/issues/detail?id=184847
   2034 TEST(STDIO_TEST, fread_EOF_184847) {
   2035   TemporaryFile tf;
   2036   char buf[6] = {0};
   2037 
   2038   FILE* fw = fopen(tf.filename, "w");
   2039   ASSERT_TRUE(fw != nullptr);
   2040 
   2041   FILE* fr = fopen(tf.filename, "r");
   2042   ASSERT_TRUE(fr != nullptr);
   2043 
   2044   fwrite("a", 1, 1, fw);
   2045   fflush(fw);
   2046   ASSERT_EQ(1U, fread(buf, 1, 1, fr));
   2047   ASSERT_STREQ("a", buf);
   2048 
   2049   // 'fr' is now at EOF.
   2050   ASSERT_EQ(0U, fread(buf, 1, 1, fr));
   2051   ASSERT_TRUE(feof(fr));
   2052 
   2053   // Write some more...
   2054   fwrite("z", 1, 1, fw);
   2055   fflush(fw);
   2056 
   2057   // ...and check that we can read it back.
   2058   // (BSD thinks that once a stream has hit EOF, it must always return EOF. SysV disagrees.)
   2059   ASSERT_EQ(1U, fread(buf, 1, 1, fr));
   2060   ASSERT_STREQ("z", buf);
   2061 
   2062   // But now we're done.
   2063   ASSERT_EQ(0U, fread(buf, 1, 1, fr));
   2064 
   2065   fclose(fr);
   2066   fclose(fw);
   2067 }
   2068 
   2069 TEST(STDIO_TEST, fclose_invalidates_fd) {
   2070   // The typical error we're trying to help people catch involves accessing
   2071   // memory after it's been freed. But we know that stdin/stdout/stderr are
   2072   // special and don't get deallocated, so this test uses stdin.
   2073   ASSERT_EQ(0, fclose(stdin));
   2074 
   2075   // Even though using a FILE* after close is undefined behavior, I've closed
   2076   // this bug as "WAI" too many times. We shouldn't hand out stale fds,
   2077   // especially because they might actually correspond to a real stream.
   2078   errno = 0;
   2079   ASSERT_EQ(-1, fileno(stdin));
   2080   ASSERT_EQ(EBADF, errno);
   2081 }
   2082 
   2083 TEST(STDIO_TEST, fseek_ftell_unseekable) {
   2084 #if defined(__BIONIC__) // glibc has fopencookie instead.
   2085   auto read_fn = [](void*, char*, int) { return -1; };
   2086   FILE* fp = funopen(nullptr, read_fn, nullptr, nullptr, nullptr);
   2087   ASSERT_TRUE(fp != nullptr);
   2088 
   2089   // Check that ftell balks on an unseekable FILE*.
   2090   errno = 0;
   2091   ASSERT_EQ(-1, ftell(fp));
   2092   ASSERT_EQ(ESPIPE, errno);
   2093 
   2094   // SEEK_CUR is rewritten as SEEK_SET internally...
   2095   errno = 0;
   2096   ASSERT_EQ(-1, fseek(fp, 0, SEEK_CUR));
   2097   ASSERT_EQ(ESPIPE, errno);
   2098 
   2099   // ...so it's worth testing the direct seek path too.
   2100   errno = 0;
   2101   ASSERT_EQ(-1, fseek(fp, 0, SEEK_SET));
   2102   ASSERT_EQ(ESPIPE, errno);
   2103 
   2104   fclose(fp);
   2105 #else
   2106   GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
   2107 #endif
   2108 }
   2109 
   2110 TEST(STDIO_TEST, funopen_EINVAL) {
   2111 #if defined(__BIONIC__)
   2112   errno = 0;
   2113   ASSERT_EQ(nullptr, funopen(nullptr, nullptr, nullptr, nullptr, nullptr));
   2114   ASSERT_EQ(EINVAL, errno);
   2115 #else
   2116   GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
   2117 #endif
   2118 }
   2119 
   2120 TEST(STDIO_TEST, funopen_seek) {
   2121 #if defined(__BIONIC__)
   2122   auto read_fn = [](void*, char*, int) { return -1; };
   2123 
   2124   auto seek_fn = [](void*, fpos_t, int) -> fpos_t { return 0xfedcba12; };
   2125   auto seek64_fn = [](void*, fpos64_t, int) -> fpos64_t { return 0xfedcba12345678; };
   2126 
   2127   FILE* fp = funopen(nullptr, read_fn, nullptr, seek_fn, nullptr);
   2128   ASSERT_TRUE(fp != nullptr);
   2129   fpos_t pos;
   2130 #if defined(__LP64__)
   2131   EXPECT_EQ(0, fgetpos(fp, &pos)) << strerror(errno);
   2132   EXPECT_EQ(0xfedcba12LL, pos);
   2133 #else
   2134   EXPECT_EQ(-1, fgetpos(fp, &pos)) << strerror(errno);
   2135   EXPECT_EQ(EOVERFLOW, errno);
   2136 #endif
   2137 
   2138   FILE* fp64 = funopen64(nullptr, read_fn, nullptr, seek64_fn, nullptr);
   2139   ASSERT_TRUE(fp64 != nullptr);
   2140   fpos64_t pos64;
   2141   EXPECT_EQ(0, fgetpos64(fp64, &pos64)) << strerror(errno);
   2142   EXPECT_EQ(0xfedcba12345678, pos64);
   2143 #else
   2144   GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
   2145 #endif
   2146 }
   2147 
   2148 TEST(STDIO_TEST, lots_of_concurrent_files) {
   2149   std::vector<TemporaryFile*> tfs;
   2150   std::vector<FILE*> fps;
   2151 
   2152   for (size_t i = 0; i < 256; ++i) {
   2153     TemporaryFile* tf = new TemporaryFile;
   2154     tfs.push_back(tf);
   2155     FILE* fp = fopen(tf->filename, "w+");
   2156     fps.push_back(fp);
   2157     fprintf(fp, "hello %zu!\n", i);
   2158     fflush(fp);
   2159   }
   2160 
   2161   for (size_t i = 0; i < 256; ++i) {
   2162     char expected[BUFSIZ];
   2163     snprintf(expected, sizeof(expected), "hello %zu!\n", i);
   2164 
   2165     AssertFileIs(fps[i], expected);
   2166     fclose(fps[i]);
   2167     delete tfs[i];
   2168   }
   2169 }
   2170 
   2171 static void AssertFileOffsetAt(FILE* fp, off64_t offset) {
   2172   EXPECT_EQ(offset, ftell(fp));
   2173   EXPECT_EQ(offset, ftello(fp));
   2174   EXPECT_EQ(offset, ftello64(fp));
   2175   fpos_t pos;
   2176   fpos64_t pos64;
   2177   EXPECT_EQ(0, fgetpos(fp, &pos));
   2178   EXPECT_EQ(0, fgetpos64(fp, &pos64));
   2179 #if defined(__BIONIC__)
   2180   EXPECT_EQ(offset, static_cast<off64_t>(pos));
   2181   EXPECT_EQ(offset, static_cast<off64_t>(pos64));
   2182 #else
   2183   GTEST_LOG_(INFO) << "glibc's fpos_t is opaque.\n";
   2184 #endif
   2185 }
   2186 
   2187 TEST(STDIO_TEST, seek_tell_family_smoke) {
   2188   TemporaryFile tf;
   2189   FILE* fp = fdopen(tf.fd, "w+");
   2190 
   2191   // Initially we should be at 0.
   2192   AssertFileOffsetAt(fp, 0);
   2193 
   2194   // Seek to offset 8192.
   2195   ASSERT_EQ(0, fseek(fp, 8192, SEEK_SET));
   2196   AssertFileOffsetAt(fp, 8192);
   2197   fpos_t eight_k_pos;
   2198   ASSERT_EQ(0, fgetpos(fp, &eight_k_pos));
   2199 
   2200   // Seek forward another 8192...
   2201   ASSERT_EQ(0, fseek(fp, 8192, SEEK_CUR));
   2202   AssertFileOffsetAt(fp, 8192 + 8192);
   2203   fpos64_t sixteen_k_pos64;
   2204   ASSERT_EQ(0, fgetpos64(fp, &sixteen_k_pos64));
   2205 
   2206   // Seek back 8192...
   2207   ASSERT_EQ(0, fseek(fp, -8192, SEEK_CUR));
   2208   AssertFileOffsetAt(fp, 8192);
   2209 
   2210   // Since we haven't written anything, the end is also at 0.
   2211   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   2212   AssertFileOffsetAt(fp, 0);
   2213 
   2214   // Check that our fpos64_t from 16KiB works...
   2215   ASSERT_EQ(0, fsetpos64(fp, &sixteen_k_pos64));
   2216   AssertFileOffsetAt(fp, 8192 + 8192);
   2217   // ...as does our fpos_t from 8192.
   2218   ASSERT_EQ(0, fsetpos(fp, &eight_k_pos));
   2219   AssertFileOffsetAt(fp, 8192);
   2220 
   2221   // Do fseeko and fseeko64 work too?
   2222   ASSERT_EQ(0, fseeko(fp, 1234, SEEK_SET));
   2223   AssertFileOffsetAt(fp, 1234);
   2224   ASSERT_EQ(0, fseeko64(fp, 5678, SEEK_SET));
   2225   AssertFileOffsetAt(fp, 5678);
   2226 
   2227   fclose(fp);
   2228 }
   2229 
   2230 TEST(STDIO_TEST, fseek_fseeko_EINVAL) {
   2231   TemporaryFile tf;
   2232   FILE* fp = fdopen(tf.fd, "w+");
   2233 
   2234   // Bad whence.
   2235   errno = 0;
   2236   ASSERT_EQ(-1, fseek(fp, 0, 123));
   2237   ASSERT_EQ(EINVAL, errno);
   2238   errno = 0;
   2239   ASSERT_EQ(-1, fseeko(fp, 0, 123));
   2240   ASSERT_EQ(EINVAL, errno);
   2241   errno = 0;
   2242   ASSERT_EQ(-1, fseeko64(fp, 0, 123));
   2243   ASSERT_EQ(EINVAL, errno);
   2244 
   2245   // Bad offset.
   2246   errno = 0;
   2247   ASSERT_EQ(-1, fseek(fp, -1, SEEK_SET));
   2248   ASSERT_EQ(EINVAL, errno);
   2249   errno = 0;
   2250   ASSERT_EQ(-1, fseeko(fp, -1, SEEK_SET));
   2251   ASSERT_EQ(EINVAL, errno);
   2252   errno = 0;
   2253   ASSERT_EQ(-1, fseeko64(fp, -1, SEEK_SET));
   2254   ASSERT_EQ(EINVAL, errno);
   2255 
   2256   fclose(fp);
   2257 }
   2258 
   2259 TEST(STDIO_TEST, ctermid) {
   2260   ASSERT_STREQ("/dev/tty", ctermid(nullptr));
   2261 
   2262   char buf[L_ctermid] = {};
   2263   ASSERT_EQ(buf, ctermid(buf));
   2264   ASSERT_STREQ("/dev/tty", buf);
   2265 }
   2266 
   2267 TEST(STDIO_TEST, remove) {
   2268   struct stat sb;
   2269 
   2270   TemporaryFile tf;
   2271   ASSERT_EQ(0, remove(tf.filename));
   2272   ASSERT_EQ(-1, lstat(tf.filename, &sb));
   2273   ASSERT_EQ(ENOENT, errno);
   2274 
   2275   TemporaryDir td;
   2276   ASSERT_EQ(0, remove(td.dirname));
   2277   ASSERT_EQ(-1, lstat(td.dirname, &sb));
   2278   ASSERT_EQ(ENOENT, errno);
   2279 
   2280   errno = 0;
   2281   ASSERT_EQ(-1, remove(tf.filename));
   2282   ASSERT_EQ(ENOENT, errno);
   2283 
   2284   errno = 0;
   2285   ASSERT_EQ(-1, remove(td.dirname));
   2286   ASSERT_EQ(ENOENT, errno);
   2287 }
   2288 
   2289 TEST(STDIO_DEATHTEST, snprintf_30445072_known_buffer_size) {
   2290   char buf[16];
   2291   ASSERT_EXIT(snprintf(buf, atol("-1"), "hello"),
   2292               testing::KilledBySignal(SIGABRT),
   2293 #if defined(NOFORTIFY)
   2294               "FORTIFY: vsnprintf: size .* > SSIZE_MAX"
   2295 #else
   2296               "FORTIFY: vsnprintf: prevented .*-byte write into 16-byte buffer"
   2297 #endif
   2298               );
   2299 }
   2300 
   2301 TEST(STDIO_DEATHTEST, snprintf_30445072_unknown_buffer_size) {
   2302   std::string buf = "world";
   2303   ASSERT_EXIT(snprintf(&buf[0], atol("-1"), "hello"),
   2304               testing::KilledBySignal(SIGABRT),
   2305               "FORTIFY: vsnprintf: size .* > SSIZE_MAX");
   2306 }
   2307 
   2308 TEST(STDIO_TEST, sprintf_30445072) {
   2309   std::string buf = "world";
   2310   sprintf(&buf[0], "hello");
   2311   ASSERT_EQ(buf, "hello");
   2312 }
   2313 
   2314 TEST(STDIO_TEST, fopen_append_mode_and_ftell) {
   2315   TemporaryFile tf;
   2316   SetFileTo(tf.filename, "0123456789");
   2317   FILE* fp = fopen(tf.filename, "a");
   2318   EXPECT_EQ(10, ftell(fp));
   2319   ASSERT_EQ(0, fseek(fp, 2, SEEK_SET));
   2320   EXPECT_EQ(2, ftell(fp));
   2321   ASSERT_NE(EOF, fputs("xxx", fp));
   2322   ASSERT_EQ(0, fflush(fp));
   2323   EXPECT_EQ(13, ftell(fp));
   2324   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   2325   EXPECT_EQ(13, ftell(fp));
   2326   ASSERT_EQ(0, fclose(fp));
   2327   AssertFileIs(tf.filename, "0123456789xxx");
   2328 }
   2329 
   2330 TEST(STDIO_TEST, fdopen_append_mode_and_ftell) {
   2331   TemporaryFile tf;
   2332   SetFileTo(tf.filename, "0123456789");
   2333   int fd = open(tf.filename, O_RDWR);
   2334   ASSERT_NE(-1, fd);
   2335   // POSIX: "The file position indicator associated with the new stream is set to the position
   2336   // indicated by the file offset associated with the file descriptor."
   2337   ASSERT_EQ(4, lseek(fd, 4, SEEK_SET));
   2338   FILE* fp = fdopen(fd, "a");
   2339   EXPECT_EQ(4, ftell(fp));
   2340   ASSERT_EQ(0, fseek(fp, 2, SEEK_SET));
   2341   EXPECT_EQ(2, ftell(fp));
   2342   ASSERT_NE(EOF, fputs("xxx", fp));
   2343   ASSERT_EQ(0, fflush(fp));
   2344   EXPECT_EQ(13, ftell(fp));
   2345   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   2346   EXPECT_EQ(13, ftell(fp));
   2347   ASSERT_EQ(0, fclose(fp));
   2348   AssertFileIs(tf.filename, "0123456789xxx");
   2349 }
   2350 
   2351 TEST(STDIO_TEST, freopen_append_mode_and_ftell) {
   2352   TemporaryFile tf;
   2353   SetFileTo(tf.filename, "0123456789");
   2354   FILE* other_fp = fopen("/proc/version", "r");
   2355   FILE* fp = freopen(tf.filename, "a", other_fp);
   2356   EXPECT_EQ(10, ftell(fp));
   2357   ASSERT_EQ(0, fseek(fp, 2, SEEK_SET));
   2358   EXPECT_EQ(2, ftell(fp));
   2359   ASSERT_NE(EOF, fputs("xxx", fp));
   2360   ASSERT_EQ(0, fflush(fp));
   2361   EXPECT_EQ(13, ftell(fp));
   2362   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   2363   EXPECT_EQ(13, ftell(fp));
   2364   ASSERT_EQ(0, fclose(fp));
   2365   AssertFileIs(tf.filename, "0123456789xxx");
   2366 }
   2367 
   2368 TEST(STDIO_TEST, constants) {
   2369   ASSERT_LE(FILENAME_MAX, PATH_MAX);
   2370   ASSERT_EQ(L_tmpnam, PATH_MAX);
   2371 }
   2372 
   2373 TEST(STDIO_TEST, perror) {
   2374   ExecTestHelper eth;
   2375   eth.Run([&]() { errno = EINVAL; perror("a b c"); exit(0); }, 0, "a b c: Invalid argument\n");
   2376   eth.Run([&]() { errno = EINVAL; perror(nullptr); exit(0); }, 0, "Invalid argument\n");
   2377   eth.Run([&]() { errno = EINVAL; perror(""); exit(0); }, 0, "Invalid argument\n");
   2378 }
   2379 
   2380 TEST(STDIO_TEST, puts) {
   2381   ExecTestHelper eth;
   2382   eth.Run([&]() { exit(puts("a b c")); }, 0, "a b c\n");
   2383 }
   2384 
   2385 TEST(STDIO_TEST, unlocked) {
   2386   TemporaryFile tf;
   2387 
   2388   FILE* fp = fopen(tf.filename, "w+");
   2389   ASSERT_TRUE(fp != nullptr);
   2390 
   2391   clearerr_unlocked(fp);
   2392   ASSERT_FALSE(feof_unlocked(fp));
   2393   ASSERT_FALSE(ferror_unlocked(fp));
   2394 
   2395   ASSERT_EQ(fileno(fp), fileno_unlocked(fp));
   2396 
   2397   ASSERT_NE(EOF, putc_unlocked('a', fp));
   2398   ASSERT_NE(EOF, putc('b', fp));
   2399   ASSERT_NE(EOF, fputc_unlocked('c', fp));
   2400   ASSERT_NE(EOF, fputc('d', fp));
   2401 
   2402   rewind(fp);
   2403   ASSERT_EQ('a', getc_unlocked(fp));
   2404   ASSERT_EQ('b', getc(fp));
   2405   ASSERT_EQ('c', fgetc_unlocked(fp));
   2406   ASSERT_EQ('d', fgetc(fp));
   2407 
   2408   rewind(fp);
   2409   ASSERT_EQ(2U, fwrite_unlocked("AB", 1, 2, fp));
   2410   ASSERT_EQ(2U, fwrite("CD", 1, 2, fp));
   2411   ASSERT_EQ(0, fflush_unlocked(fp));
   2412 
   2413   rewind(fp);
   2414   char buf[BUFSIZ] = {};
   2415   ASSERT_EQ(2U, fread_unlocked(&buf[0], 1, 2, fp));
   2416   ASSERT_EQ(2U, fread(&buf[2], 1, 2, fp));
   2417   ASSERT_STREQ("ABCD", buf);
   2418 
   2419   rewind(fp);
   2420   ASSERT_NE(EOF, fputs("hello ", fp));
   2421   ASSERT_NE(EOF, fputs_unlocked("world", fp));
   2422   ASSERT_NE(EOF, fputc('\n', fp));
   2423 
   2424   rewind(fp);
   2425   ASSERT_TRUE(fgets_unlocked(buf, sizeof(buf), fp) != nullptr);
   2426   ASSERT_STREQ("hello world\n", buf);
   2427 
   2428   ASSERT_EQ(0, fclose(fp));
   2429 }
   2430 
   2431 TEST(STDIO_TEST, fseek_64bit) {
   2432   TemporaryFile tf;
   2433   FILE* fp = fopen64(tf.filename, "w+");
   2434   ASSERT_TRUE(fp != nullptr);
   2435   ASSERT_EQ(0, fseeko64(fp, 0x2'0000'0000, SEEK_SET));
   2436   ASSERT_EQ(0x2'0000'0000, ftello64(fp));
   2437   ASSERT_EQ(0, fseeko64(fp, 0x1'0000'0000, SEEK_CUR));
   2438   ASSERT_EQ(0x3'0000'0000, ftello64(fp));
   2439   ASSERT_EQ(0, fclose(fp));
   2440 }
   2441 
   2442 // POSIX requires that fseek/fseeko fail with EOVERFLOW if the new file offset
   2443 // isn't representable in long/off_t.
   2444 TEST(STDIO_TEST, fseek_overflow_32bit) {
   2445   TemporaryFile tf;
   2446   FILE* fp = fopen64(tf.filename, "w+");
   2447   ASSERT_EQ(0, ftruncate64(fileno(fp), 0x2'0000'0000));
   2448 
   2449   // Bionic implements overflow checking for SEEK_CUR, but glibc doesn't.
   2450 #if defined(__BIONIC__) && !defined(__LP64__)
   2451   ASSERT_EQ(0, fseek(fp, 0x7fff'ffff, SEEK_SET));
   2452   ASSERT_EQ(-1, fseek(fp, 1, SEEK_CUR));
   2453   ASSERT_EQ(EOVERFLOW, errno);
   2454 #endif
   2455 
   2456   // Neither Bionic nor glibc implement the overflow checking for SEEK_END.
   2457   // (Aside: FreeBSD's libc is an example of a libc that checks both SEEK_CUR
   2458   // and SEEK_END -- many C libraries check neither.)
   2459   ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
   2460   ASSERT_EQ(0x2'0000'0000, ftello64(fp));
   2461 
   2462   fclose(fp);
   2463 }
   2464