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