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