blob: 8747dfc6d0617cf175263b85ef84522e5d0718e8 [file] [log] [blame]
Elliott Hughes91875dc2012-09-24 17:55:15 -07001/*
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>
Elliott Hughesc9244bd2014-05-14 13:31:35 -070020#include <fcntl.h>
Elliott Hughes1d13c642013-09-23 16:02:39 -070021#include <limits.h>
Elliott Hughes7823f322014-04-14 12:11:28 -070022#include <math.h>
Elliott Hughes91875dc2012-09-24 17:55:15 -070023#include <stdio.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
Elliott Hughes05493712014-04-17 17:30:03 -070027#include <wchar.h>
Calin Juravle03e4ebe2014-05-08 14:42:06 +010028#include <locale.h>
29
Elliott Hughese6bb5a22015-01-23 17:48:15 -080030#include <vector>
31
Calin Juravle03e4ebe2014-05-08 14:42:06 +010032#include "TemporaryFile.h"
Elliott Hughes91875dc2012-09-24 17:55:15 -070033
Christopher Ferris13f26a72016-01-13 13:47:58 -080034#if defined(NOFORTIFY)
35#define STDIO_TEST stdio_nofortify
36#else
37#define STDIO_TEST stdio
38#endif
39
Elliott Hughes70715da2016-08-01 16:35:17 -070040static void AssertFileIs(FILE* fp, const char* expected, bool is_fmemopen = false) {
41 rewind(fp);
42
43 char line[1024];
44 ASSERT_EQ(line, fgets(line, sizeof(line), fp));
45 ASSERT_STREQ(expected, line);
46
47 if (is_fmemopen) {
48 // fmemopen appends a trailing NUL byte, which probably shouldn't show up as an
49 // extra empty line, but does on every C library I tested...
50 ASSERT_EQ(line, fgets(line, sizeof(line), fp));
51 ASSERT_STREQ("", line);
52 }
53
54 // Make sure there isn't anything else in the file.
55 ASSERT_EQ(nullptr, fgets(line, sizeof(line), fp)) << "junk at end of file: " << line;
56}
57
Christopher Ferris13f26a72016-01-13 13:47:58 -080058TEST(STDIO_TEST, flockfile_18208568_stderr) {
Elliott Hughes6a03abc2014-11-03 12:32:17 -080059 // Check that we have a _recursive_ mutex for flockfile.
60 flockfile(stderr);
61 feof(stderr); // We don't care about the result, but this needs to take the lock.
62 funlockfile(stderr);
63}
64
Christopher Ferris13f26a72016-01-13 13:47:58 -080065TEST(STDIO_TEST, flockfile_18208568_regular) {
Elliott Hughes6a03abc2014-11-03 12:32:17 -080066 // We never had a bug for streams other than stdin/stdout/stderr, but test anyway.
67 FILE* fp = fopen("/dev/null", "w");
68 ASSERT_TRUE(fp != NULL);
69 flockfile(fp);
70 feof(fp);
71 funlockfile(fp);
72 fclose(fp);
73}
74
Christopher Ferris13f26a72016-01-13 13:47:58 -080075TEST(STDIO_TEST, tmpfile_fileno_fprintf_rewind_fgets) {
Elliott Hughes91875dc2012-09-24 17:55:15 -070076 FILE* fp = tmpfile();
77 ASSERT_TRUE(fp != NULL);
78
79 int fd = fileno(fp);
80 ASSERT_NE(fd, -1);
81
82 struct stat sb;
83 int rc = fstat(fd, &sb);
84 ASSERT_NE(rc, -1);
85 ASSERT_EQ(sb.st_mode & 0777, 0600U);
86
87 rc = fprintf(fp, "hello\n");
88 ASSERT_EQ(rc, 6);
89
Elliott Hughes70715da2016-08-01 16:35:17 -070090 AssertFileIs(fp, "hello\n");
Elliott Hughes91875dc2012-09-24 17:55:15 -070091 fclose(fp);
92}
Irina Tirdeaeac9eb42012-09-08 09:28:30 +030093
Elliott Hughesf226ee52016-02-03 11:24:28 -080094TEST(STDIO_TEST, tmpfile64) {
95 FILE* fp = tmpfile64();
96 ASSERT_TRUE(fp != nullptr);
97 fclose(fp);
98}
99
Christopher Ferris13f26a72016-01-13 13:47:58 -0800100TEST(STDIO_TEST, dprintf) {
Calin Juravle6afb2a92014-05-22 11:47:47 +0100101 TemporaryFile tf;
102
103 int rc = dprintf(tf.fd, "hello\n");
104 ASSERT_EQ(rc, 6);
105
Yabin Cui5ca4a9e2014-11-06 19:55:09 -0800106 lseek(tf.fd, 0, SEEK_SET);
Christopher Ferris9e01ea62014-05-29 12:49:35 -0700107 FILE* tfile = fdopen(tf.fd, "r");
108 ASSERT_TRUE(tfile != NULL);
Calin Juravle6afb2a92014-05-22 11:47:47 +0100109
Elliott Hughes70715da2016-08-01 16:35:17 -0700110 AssertFileIs(tfile, "hello\n");
Christopher Ferris9e01ea62014-05-29 12:49:35 -0700111 fclose(tfile);
Calin Juravle6afb2a92014-05-22 11:47:47 +0100112}
113
Christopher Ferris13f26a72016-01-13 13:47:58 -0800114TEST(STDIO_TEST, getdelim) {
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300115 FILE* fp = tmpfile();
116 ASSERT_TRUE(fp != NULL);
117
118 const char* line_written = "This is a test";
119 int rc = fprintf(fp, "%s", line_written);
120 ASSERT_EQ(rc, static_cast<int>(strlen(line_written)));
121
122 rewind(fp);
123
124 char* word_read = NULL;
125 size_t allocated_length = 0;
126
127 const char* expected[] = { "This ", " ", "is ", "a ", "test" };
128 for (size_t i = 0; i < 5; ++i) {
129 ASSERT_FALSE(feof(fp));
130 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), static_cast<int>(strlen(expected[i])));
131 ASSERT_GE(allocated_length, strlen(expected[i]));
Elliott Hughes0ed7e082015-01-22 15:13:38 -0800132 ASSERT_STREQ(expected[i], word_read);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300133 }
134 // The last read should have set the end-of-file indicator for the stream.
135 ASSERT_TRUE(feof(fp));
136 clearerr(fp);
137
138 // getdelim returns -1 but doesn't set errno if we're already at EOF.
139 // It should set the end-of-file indicator for the stream, though.
140 errno = 0;
141 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800142 ASSERT_EQ(0, errno);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300143 ASSERT_TRUE(feof(fp));
144
145 free(word_read);
146 fclose(fp);
147}
148
Christopher Ferris13f26a72016-01-13 13:47:58 -0800149TEST(STDIO_TEST, getdelim_invalid) {
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300150 FILE* fp = tmpfile();
Elliott Hughes6ad8f762013-12-19 14:56:17 -0800151 ASSERT_TRUE(fp != NULL);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300152
153 char* buffer = NULL;
154 size_t buffer_length = 0;
155
156 // The first argument can't be NULL.
157 errno = 0;
158 ASSERT_EQ(getdelim(NULL, &buffer_length, ' ', fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800159 ASSERT_EQ(EINVAL, errno);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300160
161 // The second argument can't be NULL.
162 errno = 0;
163 ASSERT_EQ(getdelim(&buffer, NULL, ' ', fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800164 ASSERT_EQ(EINVAL, errno);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300165
Elliott Hughes20f8aec2014-05-12 15:15:37 -0700166 // The underlying fd can't be closed.
167 ASSERT_EQ(0, close(fileno(fp)));
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300168 errno = 0;
169 ASSERT_EQ(getdelim(&buffer, &buffer_length, ' ', fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800170 ASSERT_EQ(EBADF, errno);
Elliott Hughes20f8aec2014-05-12 15:15:37 -0700171 fclose(fp);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300172}
173
Christopher Ferris13f26a72016-01-13 13:47:58 -0800174TEST(STDIO_TEST, getdelim_directory) {
Elliott Hughes694fd2d2015-04-05 10:51:56 -0700175 FILE* fp = fopen("/proc", "r");
176 ASSERT_TRUE(fp != NULL);
177 char* word_read;
178 size_t allocated_length;
179 ASSERT_EQ(-1, getdelim(&word_read, &allocated_length, ' ', fp));
180 fclose(fp);
181}
182
Christopher Ferris13f26a72016-01-13 13:47:58 -0800183TEST(STDIO_TEST, getline) {
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300184 FILE* fp = tmpfile();
185 ASSERT_TRUE(fp != NULL);
186
187 const char* line_written = "This is a test for getline\n";
188 const size_t line_count = 5;
189
190 for (size_t i = 0; i < line_count; ++i) {
191 int rc = fprintf(fp, "%s", line_written);
192 ASSERT_EQ(rc, static_cast<int>(strlen(line_written)));
193 }
194
195 rewind(fp);
196
197 char* line_read = NULL;
198 size_t allocated_length = 0;
199
200 size_t read_line_count = 0;
201 ssize_t read_char_count;
202 while ((read_char_count = getline(&line_read, &allocated_length, fp)) != -1) {
203 ASSERT_EQ(read_char_count, static_cast<int>(strlen(line_written)));
204 ASSERT_GE(allocated_length, strlen(line_written));
Elliott Hughes0ed7e082015-01-22 15:13:38 -0800205 ASSERT_STREQ(line_written, line_read);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300206 ++read_line_count;
207 }
208 ASSERT_EQ(read_line_count, line_count);
209
210 // The last read should have set the end-of-file indicator for the stream.
211 ASSERT_TRUE(feof(fp));
212 clearerr(fp);
213
214 // getline returns -1 but doesn't set errno if we're already at EOF.
215 // It should set the end-of-file indicator for the stream, though.
216 errno = 0;
217 ASSERT_EQ(getline(&line_read, &allocated_length, fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800218 ASSERT_EQ(0, errno);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300219 ASSERT_TRUE(feof(fp));
220
221 free(line_read);
222 fclose(fp);
223}
224
Christopher Ferris13f26a72016-01-13 13:47:58 -0800225TEST(STDIO_TEST, getline_invalid) {
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300226 FILE* fp = tmpfile();
Elliott Hughes6ad8f762013-12-19 14:56:17 -0800227 ASSERT_TRUE(fp != NULL);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300228
229 char* buffer = NULL;
230 size_t buffer_length = 0;
231
232 // The first argument can't be NULL.
233 errno = 0;
234 ASSERT_EQ(getline(NULL, &buffer_length, fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800235 ASSERT_EQ(EINVAL, errno);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300236
237 // The second argument can't be NULL.
238 errno = 0;
239 ASSERT_EQ(getline(&buffer, NULL, fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800240 ASSERT_EQ(EINVAL, errno);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300241
Elliott Hughes20f8aec2014-05-12 15:15:37 -0700242 // The underlying fd can't be closed.
243 ASSERT_EQ(0, close(fileno(fp)));
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300244 errno = 0;
245 ASSERT_EQ(getline(&buffer, &buffer_length, fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800246 ASSERT_EQ(EBADF, errno);
Elliott Hughes20f8aec2014-05-12 15:15:37 -0700247 fclose(fp);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300248}
Thorsten Glaserc641caf2013-02-17 16:50:58 +0000249
Christopher Ferris13f26a72016-01-13 13:47:58 -0800250TEST(STDIO_TEST, printf_ssize_t) {
Elliott Hughese2556422013-02-28 10:51:14 -0800251 // http://b/8253769
Elliott Hughese2556422013-02-28 10:51:14 -0800252 ASSERT_EQ(sizeof(ssize_t), sizeof(long int));
Elliott Hughesb6e22482013-03-08 15:28:52 -0800253 ASSERT_EQ(sizeof(ssize_t), sizeof(size_t));
254 // For our 32-bit ABI, we had a ssize_t definition that confuses GCC into saying:
Thorsten Glaserc641caf2013-02-17 16:50:58 +0000255 // error: format '%zd' expects argument of type 'signed size_t',
256 // but argument 4 has type 'ssize_t {aka long int}' [-Werror=format]
257 ssize_t v = 1;
258 char buf[32];
259 snprintf(buf, sizeof(buf), "%zd", v);
260}
Elliott Hughes6b3f49a2013-03-06 16:20:55 -0800261
Elliott Hughes05493712014-04-17 17:30:03 -0700262// https://code.google.com/p/android/issues/detail?id=64886
Christopher Ferris13f26a72016-01-13 13:47:58 -0800263TEST(STDIO_TEST, snprintf_a) {
Elliott Hughes05493712014-04-17 17:30:03 -0700264 char buf[BUFSIZ];
265 EXPECT_EQ(23, snprintf(buf, sizeof(buf), "<%a>", 9990.235));
266 EXPECT_STREQ("<0x1.3831e147ae148p+13>", buf);
267}
268
Christopher Ferris13f26a72016-01-13 13:47:58 -0800269TEST(STDIO_TEST, snprintf_lc) {
Elliott Hughes05493712014-04-17 17:30:03 -0700270 char buf[BUFSIZ];
271 wint_t wc = L'a';
272 EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%lc>", wc));
273 EXPECT_STREQ("<a>", buf);
274}
275
Christopher Ferris13f26a72016-01-13 13:47:58 -0800276TEST(STDIO_TEST, snprintf_ls) {
Elliott Hughes05493712014-04-17 17:30:03 -0700277 char buf[BUFSIZ];
278 wchar_t* ws = NULL;
279 EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%ls>", ws));
280 EXPECT_STREQ("<(null)>", buf);
281
282 wchar_t chars[] = { L'h', L'i', 0 };
283 ws = chars;
284 EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%ls>", ws));
285 EXPECT_STREQ("<hi>", buf);
286}
287
Christopher Ferris13f26a72016-01-13 13:47:58 -0800288TEST(STDIO_TEST, snprintf_n) {
Elliott Hughes063525c2014-05-13 11:19:57 -0700289#if defined(__BIONIC__)
Elliott Hughese2341d02014-05-02 18:16:32 -0700290 // http://b/14492135
Elliott Hughes7248a2d2013-09-24 18:01:33 -0700291 char buf[32];
Elliott Hughese2341d02014-05-02 18:16:32 -0700292 int i = 1234;
293 EXPECT_EQ(5, snprintf(buf, sizeof(buf), "a %n b", &i));
294 EXPECT_EQ(1234, i);
295 EXPECT_STREQ("a n b", buf);
296#else
Elliott Hughes9677fab2016-01-25 15:50:59 -0800297 GTEST_LOG_(INFO) << "This test does nothing on glibc.\n";
Elliott Hughese2341d02014-05-02 18:16:32 -0700298#endif
Elliott Hughes7248a2d2013-09-24 18:01:33 -0700299}
Elliott Hughes7248a2d2013-09-24 18:01:33 -0700300
Christopher Ferris13f26a72016-01-13 13:47:58 -0800301TEST(STDIO_TEST, snprintf_smoke) {
Elliott Hughes1d13c642013-09-23 16:02:39 -0700302 char buf[BUFSIZ];
303
304 snprintf(buf, sizeof(buf), "a");
305 EXPECT_STREQ("a", buf);
306
307 snprintf(buf, sizeof(buf), "%%");
308 EXPECT_STREQ("%", buf);
309
310 snprintf(buf, sizeof(buf), "01234");
311 EXPECT_STREQ("01234", buf);
312
313 snprintf(buf, sizeof(buf), "a%sb", "01234");
314 EXPECT_STREQ("a01234b", buf);
315
316 char* s = NULL;
317 snprintf(buf, sizeof(buf), "a%sb", s);
318 EXPECT_STREQ("a(null)b", buf);
319
320 snprintf(buf, sizeof(buf), "aa%scc", "bb");
321 EXPECT_STREQ("aabbcc", buf);
322
323 snprintf(buf, sizeof(buf), "a%cc", 'b');
324 EXPECT_STREQ("abc", buf);
325
326 snprintf(buf, sizeof(buf), "a%db", 1234);
327 EXPECT_STREQ("a1234b", buf);
328
329 snprintf(buf, sizeof(buf), "a%db", -8123);
330 EXPECT_STREQ("a-8123b", buf);
331
Stephen Hines6c7b3cb2013-10-11 16:03:21 -0700332 snprintf(buf, sizeof(buf), "a%hdb", static_cast<short>(0x7fff0010));
Elliott Hughes1d13c642013-09-23 16:02:39 -0700333 EXPECT_STREQ("a16b", buf);
334
Stephen Hines6c7b3cb2013-10-11 16:03:21 -0700335 snprintf(buf, sizeof(buf), "a%hhdb", static_cast<char>(0x7fffff10));
Elliott Hughes1d13c642013-09-23 16:02:39 -0700336 EXPECT_STREQ("a16b", buf);
337
338 snprintf(buf, sizeof(buf), "a%lldb", 0x1000000000LL);
339 EXPECT_STREQ("a68719476736b", buf);
340
341 snprintf(buf, sizeof(buf), "a%ldb", 70000L);
342 EXPECT_STREQ("a70000b", buf);
343
344 snprintf(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234));
345 EXPECT_STREQ("a0xb0001234b", buf);
346
347 snprintf(buf, sizeof(buf), "a%xz", 0x12ab);
348 EXPECT_STREQ("a12abz", buf);
349
350 snprintf(buf, sizeof(buf), "a%Xz", 0x12ab);
351 EXPECT_STREQ("a12ABz", buf);
352
353 snprintf(buf, sizeof(buf), "a%08xz", 0x123456);
354 EXPECT_STREQ("a00123456z", buf);
355
356 snprintf(buf, sizeof(buf), "a%5dz", 1234);
357 EXPECT_STREQ("a 1234z", buf);
358
359 snprintf(buf, sizeof(buf), "a%05dz", 1234);
360 EXPECT_STREQ("a01234z", buf);
361
362 snprintf(buf, sizeof(buf), "a%8dz", 1234);
363 EXPECT_STREQ("a 1234z", buf);
364
365 snprintf(buf, sizeof(buf), "a%-8dz", 1234);
366 EXPECT_STREQ("a1234 z", buf);
367
368 snprintf(buf, sizeof(buf), "A%-11sZ", "abcdef");
369 EXPECT_STREQ("Aabcdef Z", buf);
370
371 snprintf(buf, sizeof(buf), "A%s:%dZ", "hello", 1234);
372 EXPECT_STREQ("Ahello:1234Z", buf);
373
374 snprintf(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5);
375 EXPECT_STREQ("a005:5:05z", buf);
376
377 void* p = NULL;
378 snprintf(buf, sizeof(buf), "a%d,%pz", 5, p);
Christopher Ferris13613132013-10-28 15:24:04 -0700379#if defined(__BIONIC__)
Elliott Hughes1d13c642013-09-23 16:02:39 -0700380 EXPECT_STREQ("a5,0x0z", buf);
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800381#else // __BIONIC__
Christopher Ferris13613132013-10-28 15:24:04 -0700382 EXPECT_STREQ("a5,(nil)z", buf);
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800383#endif // __BIONIC__
Elliott Hughes1d13c642013-09-23 16:02:39 -0700384
385 snprintf(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8);
386 EXPECT_STREQ("a68719476736,6,7,8z", buf);
387
388 snprintf(buf, sizeof(buf), "a_%f_b", 1.23f);
389 EXPECT_STREQ("a_1.230000_b", buf);
390
Stephen Hines6c7b3cb2013-10-11 16:03:21 -0700391 snprintf(buf, sizeof(buf), "a_%g_b", 3.14);
Elliott Hughes1d13c642013-09-23 16:02:39 -0700392 EXPECT_STREQ("a_3.14_b", buf);
Alexander Ivchenkoedd7c2e2014-04-01 17:01:39 +0400393
394 snprintf(buf, sizeof(buf), "%1$s %1$s", "print_me_twice");
395 EXPECT_STREQ("print_me_twice print_me_twice", buf);
Elliott Hughes1d13c642013-09-23 16:02:39 -0700396}
397
Elliott Hughes1b18aff2014-12-16 14:45:32 -0800398template <typename T>
399void CheckInfNan(int snprintf_fn(T*, size_t, const T*, ...),
400 const T* fmt, const T* fmt_plus,
401 const T* minus_inf, const T* inf_, const T* plus_inf,
402 const T* minus_nan, const T* nan_, const T* plus_nan) {
403 T buf[BUFSIZ];
Elliott Hughes7823f322014-04-14 12:11:28 -0700404
Elliott Hughes1b18aff2014-12-16 14:45:32 -0800405 snprintf_fn(buf, sizeof(buf), fmt, nan(""));
406 EXPECT_STREQ(nan_, buf) << fmt;
407 snprintf_fn(buf, sizeof(buf), fmt, -nan(""));
408 EXPECT_STREQ(minus_nan, buf) << fmt;
409 snprintf_fn(buf, sizeof(buf), fmt_plus, nan(""));
410 EXPECT_STREQ(plus_nan, buf) << fmt_plus;
411 snprintf_fn(buf, sizeof(buf), fmt_plus, -nan(""));
412 EXPECT_STREQ(minus_nan, buf) << fmt_plus;
413
414 snprintf_fn(buf, sizeof(buf), fmt, HUGE_VAL);
415 EXPECT_STREQ(inf_, buf) << fmt;
416 snprintf_fn(buf, sizeof(buf), fmt, -HUGE_VAL);
417 EXPECT_STREQ(minus_inf, buf) << fmt;
418 snprintf_fn(buf, sizeof(buf), fmt_plus, HUGE_VAL);
419 EXPECT_STREQ(plus_inf, buf) << fmt_plus;
420 snprintf_fn(buf, sizeof(buf), fmt_plus, -HUGE_VAL);
421 EXPECT_STREQ(minus_inf, buf) << fmt_plus;
Elliott Hughes7823f322014-04-14 12:11:28 -0700422}
423
Christopher Ferris13f26a72016-01-13 13:47:58 -0800424TEST(STDIO_TEST, snprintf_inf_nan) {
Elliott Hughes1b18aff2014-12-16 14:45:32 -0800425 CheckInfNan(snprintf, "%a", "%+a", "-inf", "inf", "+inf", "-nan", "nan", "+nan");
426 CheckInfNan(snprintf, "%A", "%+A", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN");
427 CheckInfNan(snprintf, "%e", "%+e", "-inf", "inf", "+inf", "-nan", "nan", "+nan");
428 CheckInfNan(snprintf, "%E", "%+E", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN");
429 CheckInfNan(snprintf, "%f", "%+f", "-inf", "inf", "+inf", "-nan", "nan", "+nan");
430 CheckInfNan(snprintf, "%F", "%+F", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN");
431 CheckInfNan(snprintf, "%g", "%+g", "-inf", "inf", "+inf", "-nan", "nan", "+nan");
432 CheckInfNan(snprintf, "%G", "%+G", "-INF", "INF", "+INF", "-NAN", "NAN", "+NAN");
433}
Elliott Hughes7823f322014-04-14 12:11:28 -0700434
Christopher Ferris13f26a72016-01-13 13:47:58 -0800435TEST(STDIO_TEST, wsprintf_inf_nan) {
Elliott Hughes1b18aff2014-12-16 14:45:32 -0800436 CheckInfNan(swprintf, L"%a", L"%+a", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan");
437 CheckInfNan(swprintf, L"%A", L"%+A", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN");
438 CheckInfNan(swprintf, L"%e", L"%+e", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan");
439 CheckInfNan(swprintf, L"%E", L"%+E", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN");
440 CheckInfNan(swprintf, L"%f", L"%+f", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan");
441 CheckInfNan(swprintf, L"%F", L"%+F", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN");
442 CheckInfNan(swprintf, L"%g", L"%+g", L"-inf", L"inf", L"+inf", L"-nan", L"nan", L"+nan");
443 CheckInfNan(swprintf, L"%G", L"%+G", L"-INF", L"INF", L"+INF", L"-NAN", L"NAN", L"+NAN");
Elliott Hughes7823f322014-04-14 12:11:28 -0700444}
445
Christopher Ferris13f26a72016-01-13 13:47:58 -0800446TEST(STDIO_TEST, snprintf_d_INT_MAX) {
Elliott Hughes1d13c642013-09-23 16:02:39 -0700447 char buf[BUFSIZ];
448 snprintf(buf, sizeof(buf), "%d", INT_MAX);
449 EXPECT_STREQ("2147483647", buf);
450}
451
Christopher Ferris13f26a72016-01-13 13:47:58 -0800452TEST(STDIO_TEST, snprintf_d_INT_MIN) {
Elliott Hughes1d13c642013-09-23 16:02:39 -0700453 char buf[BUFSIZ];
454 snprintf(buf, sizeof(buf), "%d", INT_MIN);
455 EXPECT_STREQ("-2147483648", buf);
456}
457
Christopher Ferris13f26a72016-01-13 13:47:58 -0800458TEST(STDIO_TEST, snprintf_ld_LONG_MAX) {
Elliott Hughes1d13c642013-09-23 16:02:39 -0700459 char buf[BUFSIZ];
460 snprintf(buf, sizeof(buf), "%ld", LONG_MAX);
Elliott Hughes925753a2013-10-18 13:17:18 -0700461#if __LP64__
462 EXPECT_STREQ("9223372036854775807", buf);
463#else
Elliott Hughes1d13c642013-09-23 16:02:39 -0700464 EXPECT_STREQ("2147483647", buf);
Elliott Hughes925753a2013-10-18 13:17:18 -0700465#endif
Elliott Hughes1d13c642013-09-23 16:02:39 -0700466}
467
Christopher Ferris13f26a72016-01-13 13:47:58 -0800468TEST(STDIO_TEST, snprintf_ld_LONG_MIN) {
Elliott Hughes1d13c642013-09-23 16:02:39 -0700469 char buf[BUFSIZ];
470 snprintf(buf, sizeof(buf), "%ld", LONG_MIN);
Elliott Hughes925753a2013-10-18 13:17:18 -0700471#if __LP64__
472 EXPECT_STREQ("-9223372036854775808", buf);
473#else
Elliott Hughes1d13c642013-09-23 16:02:39 -0700474 EXPECT_STREQ("-2147483648", buf);
Elliott Hughes925753a2013-10-18 13:17:18 -0700475#endif
Elliott Hughes1d13c642013-09-23 16:02:39 -0700476}
477
Christopher Ferris13f26a72016-01-13 13:47:58 -0800478TEST(STDIO_TEST, snprintf_lld_LLONG_MAX) {
Elliott Hughes1d13c642013-09-23 16:02:39 -0700479 char buf[BUFSIZ];
480 snprintf(buf, sizeof(buf), "%lld", LLONG_MAX);
481 EXPECT_STREQ("9223372036854775807", buf);
482}
483
Christopher Ferris13f26a72016-01-13 13:47:58 -0800484TEST(STDIO_TEST, snprintf_lld_LLONG_MIN) {
Elliott Hughes1d13c642013-09-23 16:02:39 -0700485 char buf[BUFSIZ];
486 snprintf(buf, sizeof(buf), "%lld", LLONG_MIN);
487 EXPECT_STREQ("-9223372036854775808", buf);
488}
489
Christopher Ferris13f26a72016-01-13 13:47:58 -0800490TEST(STDIO_TEST, snprintf_e) {
Elliott Hughes4bd97ce2014-04-10 17:48:14 -0700491 char buf[BUFSIZ];
492
493 snprintf(buf, sizeof(buf), "%e", 1.5);
494 EXPECT_STREQ("1.500000e+00", buf);
495
496 snprintf(buf, sizeof(buf), "%Le", 1.5l);
497 EXPECT_STREQ("1.500000e+00", buf);
498}
499
Christopher Ferris13f26a72016-01-13 13:47:58 -0800500TEST(STDIO_TEST, snprintf_negative_zero_5084292) {
Elliott Hughese77f38f2014-05-14 12:39:12 -0700501 char buf[BUFSIZ];
502
Elliott Hughes1b18aff2014-12-16 14:45:32 -0800503 snprintf(buf, sizeof(buf), "%e", -0.0);
504 EXPECT_STREQ("-0.000000e+00", buf);
505 snprintf(buf, sizeof(buf), "%E", -0.0);
506 EXPECT_STREQ("-0.000000E+00", buf);
Elliott Hughese77f38f2014-05-14 12:39:12 -0700507 snprintf(buf, sizeof(buf), "%f", -0.0);
508 EXPECT_STREQ("-0.000000", buf);
Elliott Hughes1b18aff2014-12-16 14:45:32 -0800509 snprintf(buf, sizeof(buf), "%F", -0.0);
510 EXPECT_STREQ("-0.000000", buf);
511 snprintf(buf, sizeof(buf), "%g", -0.0);
512 EXPECT_STREQ("-0", buf);
513 snprintf(buf, sizeof(buf), "%G", -0.0);
514 EXPECT_STREQ("-0", buf);
515 snprintf(buf, sizeof(buf), "%a", -0.0);
516 EXPECT_STREQ("-0x0p+0", buf);
517 snprintf(buf, sizeof(buf), "%A", -0.0);
518 EXPECT_STREQ("-0X0P+0", buf);
Elliott Hughese77f38f2014-05-14 12:39:12 -0700519}
520
Christopher Ferris13f26a72016-01-13 13:47:58 -0800521TEST(STDIO_TEST, snprintf_utf8_15439554) {
Dan Albert1aec7c12014-07-30 10:53:48 -0700522 locale_t cloc = newlocale(LC_ALL, "C.UTF-8", 0);
Wally Yaua40fdbd2014-08-26 09:47:23 -0700523 locale_t old_locale = uselocale(cloc);
Dan Albert1aec7c12014-07-30 10:53:48 -0700524
Elliott Hughes69f05d22014-06-05 20:10:09 -0700525 // http://b/15439554
526 char buf[BUFSIZ];
527
528 // 1-byte character.
529 snprintf(buf, sizeof(buf), "%dx%d", 1, 2);
530 EXPECT_STREQ("1x2", buf);
531 // 2-byte character.
532 snprintf(buf, sizeof(buf), "%d\xc2\xa2%d", 1, 2);
533 EXPECT_STREQ("1¢2", buf);
534 // 3-byte character.
535 snprintf(buf, sizeof(buf), "%d\xe2\x82\xac%d", 1, 2);
536 EXPECT_STREQ("1€2", buf);
537 // 4-byte character.
538 snprintf(buf, sizeof(buf), "%d\xf0\xa4\xad\xa2%d", 1, 2);
539 EXPECT_STREQ("1𤭢2", buf);
Dan Albert1aec7c12014-07-30 10:53:48 -0700540
Wally Yaua40fdbd2014-08-26 09:47:23 -0700541 uselocale(old_locale);
Dan Albert1aec7c12014-07-30 10:53:48 -0700542 freelocale(cloc);
Elliott Hughes69f05d22014-06-05 20:10:09 -0700543}
544
Elliott Hughes43f7c872016-02-05 11:18:41 -0800545static void* snprintf_small_stack_fn(void*) {
546 // Make life (realistically) hard for ourselves by allocating our own buffer for the result.
547 char buf[PATH_MAX];
548 snprintf(buf, sizeof(buf), "/proc/%d", getpid());
549 return nullptr;
550}
551
552TEST(STDIO_TEST, snprintf_small_stack) {
553 // Is it safe to call snprintf on a thread with a small stack?
554 // (The snprintf implementation puts some pretty large buffers on the stack.)
555 pthread_attr_t a;
556 ASSERT_EQ(0, pthread_attr_init(&a));
557 ASSERT_EQ(0, pthread_attr_setstacksize(&a, PTHREAD_STACK_MIN));
558
559 pthread_t t;
560 ASSERT_EQ(0, pthread_create(&t, &a, snprintf_small_stack_fn, nullptr));
561 ASSERT_EQ(0, pthread_join(t, nullptr));
562}
563
Elliott Hughes8200e552016-02-05 21:57:37 -0800564TEST(STDIO_TEST, snprintf_asterisk_overflow) {
565 char buf[128];
566 ASSERT_EQ(5, snprintf(buf, sizeof(buf), "%.*s%c", 4, "hello world", '!'));
567 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX/2, "hello world", '!'));
568 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX-1, "hello world", '!'));
569 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX, "hello world", '!'));
570 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", -1, "hello world", '!'));
571
572 // INT_MAX-1, INT_MAX, INT_MAX+1.
573 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.2147483646s%c", "hello world", '!'));
574 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.2147483647s%c", "hello world", '!'));
575 ASSERT_EQ(-1, snprintf(buf, sizeof(buf), "%.2147483648s%c", "hello world", '!'));
576 ASSERT_EQ(ENOMEM, errno);
577}
578
Elliott Hughes70715da2016-08-01 16:35:17 -0700579TEST(STDIO_TEST, fprintf) {
580 TemporaryFile tf;
581
582 FILE* tfile = fdopen(tf.fd, "r+");
583 ASSERT_TRUE(tfile != nullptr);
584
585 ASSERT_EQ(7, fprintf(tfile, "%d %s", 123, "abc"));
586 AssertFileIs(tfile, "123 abc");
587 fclose(tfile);
588}
589
Christopher Ferris13f26a72016-01-13 13:47:58 -0800590TEST(STDIO_TEST, fprintf_failures_7229520) {
Elliott Hughes69f05d22014-06-05 20:10:09 -0700591 // http://b/7229520
Elliott Hughesc9244bd2014-05-14 13:31:35 -0700592 FILE* fp;
593
594 // Unbuffered case where the fprintf(3) itself fails.
595 ASSERT_NE(nullptr, fp = tmpfile());
596 setbuf(fp, NULL);
597 ASSERT_EQ(4, fprintf(fp, "epic"));
598 ASSERT_EQ(0, close(fileno(fp)));
599 ASSERT_EQ(-1, fprintf(fp, "fail"));
600 ASSERT_EQ(-1, fclose(fp));
601
602 // Buffered case where we won't notice until the fclose(3).
603 // It's likely this is what was actually seen in http://b/7229520,
604 // and that expecting fprintf to fail is setting yourself up for
605 // disappointment. Remember to check fclose(3)'s return value, kids!
606 ASSERT_NE(nullptr, fp = tmpfile());
607 ASSERT_EQ(4, fprintf(fp, "epic"));
608 ASSERT_EQ(0, close(fileno(fp)));
609 ASSERT_EQ(4, fprintf(fp, "fail"));
610 ASSERT_EQ(-1, fclose(fp));
611}
612
Christopher Ferris13f26a72016-01-13 13:47:58 -0800613TEST(STDIO_TEST, popen) {
Elliott Hughes6b3f49a2013-03-06 16:20:55 -0800614 FILE* fp = popen("cat /proc/version", "r");
615 ASSERT_TRUE(fp != NULL);
616
617 char buf[16];
618 char* s = fgets(buf, sizeof(buf), fp);
619 buf[13] = '\0';
620 ASSERT_STREQ("Linux version", s);
621
622 ASSERT_EQ(0, pclose(fp));
623}
Elliott Hughes6b05c8e2013-04-11 13:54:48 -0700624
Christopher Ferris13f26a72016-01-13 13:47:58 -0800625TEST(STDIO_TEST, getc) {
Elliott Hughes6b05c8e2013-04-11 13:54:48 -0700626 FILE* fp = fopen("/proc/version", "r");
627 ASSERT_TRUE(fp != NULL);
628 ASSERT_EQ('L', getc(fp));
629 ASSERT_EQ('i', getc(fp));
630 ASSERT_EQ('n', getc(fp));
631 ASSERT_EQ('u', getc(fp));
632 ASSERT_EQ('x', getc(fp));
633 fclose(fp);
634}
635
Christopher Ferris13f26a72016-01-13 13:47:58 -0800636TEST(STDIO_TEST, putc) {
Elliott Hughes6b05c8e2013-04-11 13:54:48 -0700637 FILE* fp = fopen("/proc/version", "r");
638 ASSERT_TRUE(fp != NULL);
639 ASSERT_EQ(EOF, putc('x', fp));
640 fclose(fp);
641}
Elliott Hughes603332f2014-03-12 17:10:41 -0700642
Christopher Ferris13f26a72016-01-13 13:47:58 -0800643TEST(STDIO_TEST, sscanf) {
Elliott Hughes603332f2014-03-12 17:10:41 -0700644 char s1[123];
645 int i1;
646 double d1;
647 char s2[123];
648 ASSERT_EQ(3, sscanf(" hello 123 1.23 ", "%s %i %lf %s", s1, &i1, &d1, s2));
649 ASSERT_STREQ("hello", s1);
650 ASSERT_EQ(123, i1);
Christopher Ferrisf171b342014-03-17 16:40:26 -0700651 ASSERT_DOUBLE_EQ(1.23, d1);
Elliott Hughes603332f2014-03-12 17:10:41 -0700652}
Elliott Hughes53b24382014-05-02 18:29:25 -0700653
Christopher Ferris13f26a72016-01-13 13:47:58 -0800654TEST(STDIO_TEST, cantwrite_EBADF) {
Elliott Hughes53b24382014-05-02 18:29:25 -0700655 // If we open a file read-only...
656 FILE* fp = fopen("/proc/version", "r");
657
658 // ...all attempts to write to that file should return failure.
659
660 // They should also set errno to EBADF. This isn't POSIX, but it's traditional.
661 // glibc gets the wide-character functions wrong.
662
663 errno = 0;
664 EXPECT_EQ(EOF, putc('x', fp));
665 EXPECT_EQ(EBADF, errno);
666
667 errno = 0;
668 EXPECT_EQ(EOF, fprintf(fp, "hello"));
669 EXPECT_EQ(EBADF, errno);
670
671 errno = 0;
672 EXPECT_EQ(EOF, fwprintf(fp, L"hello"));
Elliott Hughes063525c2014-05-13 11:19:57 -0700673#if defined(__BIONIC__)
Elliott Hughes53b24382014-05-02 18:29:25 -0700674 EXPECT_EQ(EBADF, errno);
675#endif
676
677 errno = 0;
Elliott Hughes53b24382014-05-02 18:29:25 -0700678 EXPECT_EQ(0U, fwrite("hello", 1, 2, fp));
679 EXPECT_EQ(EBADF, errno);
680
681 errno = 0;
682 EXPECT_EQ(EOF, fputs("hello", fp));
683 EXPECT_EQ(EBADF, errno);
684
685 errno = 0;
686 EXPECT_EQ(WEOF, fputwc(L'x', fp));
Elliott Hughes063525c2014-05-13 11:19:57 -0700687#if defined(__BIONIC__)
Elliott Hughes53b24382014-05-02 18:29:25 -0700688 EXPECT_EQ(EBADF, errno);
689#endif
690}
Calin Juravle03e4ebe2014-05-08 14:42:06 +0100691
692// Tests that we can only have a consistent and correct fpos_t when using
693// f*pos functions (i.e. fpos doesn't get inside a multi byte character).
Christopher Ferris13f26a72016-01-13 13:47:58 -0800694TEST(STDIO_TEST, consistent_fpos_t) {
Calin Juravle03e4ebe2014-05-08 14:42:06 +0100695 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
696 uselocale(LC_GLOBAL_LOCALE);
697
698 FILE* fp = tmpfile();
699 ASSERT_TRUE(fp != NULL);
700
701 wchar_t mb_one_bytes = L'h';
702 wchar_t mb_two_bytes = 0x00a2;
703 wchar_t mb_three_bytes = 0x20ac;
704 wchar_t mb_four_bytes = 0x24b62;
705
706 // Write to file.
707 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fputwc(mb_one_bytes, fp)));
708 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp)));
709 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp)));
710 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp)));
711
712 rewind(fp);
713
714 // Record each character position.
715 fpos_t pos1;
716 fpos_t pos2;
717 fpos_t pos3;
718 fpos_t pos4;
719 fpos_t pos5;
720 EXPECT_EQ(0, fgetpos(fp, &pos1));
721 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp)));
722 EXPECT_EQ(0, fgetpos(fp, &pos2));
723 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp)));
724 EXPECT_EQ(0, fgetpos(fp, &pos3));
725 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp)));
726 EXPECT_EQ(0, fgetpos(fp, &pos4));
727 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp)));
728 EXPECT_EQ(0, fgetpos(fp, &pos5));
729
Elliott Hughes063525c2014-05-13 11:19:57 -0700730#if defined(__BIONIC__)
Calin Juravle03e4ebe2014-05-08 14:42:06 +0100731 // Bionic's fpos_t is just an alias for off_t. This is inherited from OpenBSD
732 // upstream. Glibc differs by storing the mbstate_t inside its fpos_t. In
733 // Bionic (and upstream OpenBSD) the mbstate_t is stored inside the FILE
734 // structure.
735 ASSERT_EQ(0, static_cast<off_t>(pos1));
736 ASSERT_EQ(1, static_cast<off_t>(pos2));
737 ASSERT_EQ(3, static_cast<off_t>(pos3));
738 ASSERT_EQ(6, static_cast<off_t>(pos4));
739 ASSERT_EQ(10, static_cast<off_t>(pos5));
740#endif
741
742 // Exercise back and forth movements of the position.
743 ASSERT_EQ(0, fsetpos(fp, &pos2));
744 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp)));
745 ASSERT_EQ(0, fsetpos(fp, &pos1));
746 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp)));
747 ASSERT_EQ(0, fsetpos(fp, &pos4));
748 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp)));
749 ASSERT_EQ(0, fsetpos(fp, &pos3));
750 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp)));
751 ASSERT_EQ(0, fsetpos(fp, &pos5));
752 ASSERT_EQ(WEOF, fgetwc(fp));
753
754 fclose(fp);
755}
756
757// Exercise the interaction between fpos and seek.
Christopher Ferris13f26a72016-01-13 13:47:58 -0800758TEST(STDIO_TEST, fpos_t_and_seek) {
Calin Juravle03e4ebe2014-05-08 14:42:06 +0100759 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
760 uselocale(LC_GLOBAL_LOCALE);
761
Calin Juravle9b95ea92014-05-14 17:07:10 +0100762 // In glibc-2.16 fseek doesn't work properly in wide mode
763 // (https://sourceware.org/bugzilla/show_bug.cgi?id=14543). One workaround is
764 // to close and re-open the file. We do it in order to make the test pass
765 // with all glibcs.
766
Calin Juravle03e4ebe2014-05-08 14:42:06 +0100767 TemporaryFile tf;
768 FILE* fp = fdopen(tf.fd, "w+");
769 ASSERT_TRUE(fp != NULL);
770
771 wchar_t mb_two_bytes = 0x00a2;
772 wchar_t mb_three_bytes = 0x20ac;
773 wchar_t mb_four_bytes = 0x24b62;
774
775 // Write to file.
776 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp)));
777 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp)));
778 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp)));
779
780 fflush(fp);
781 fclose(fp);
782
783 fp = fopen(tf.filename, "r");
784 ASSERT_TRUE(fp != NULL);
785
786 // Store a valid position.
787 fpos_t mb_two_bytes_pos;
788 ASSERT_EQ(0, fgetpos(fp, &mb_two_bytes_pos));
789
790 // Move inside mb_four_bytes with fseek.
791 long offset_inside_mb = 6;
792 ASSERT_EQ(0, fseek(fp, offset_inside_mb, SEEK_SET));
793
794 // Store the "inside multi byte" position.
795 fpos_t pos_inside_mb;
796 ASSERT_EQ(0, fgetpos(fp, &pos_inside_mb));
Elliott Hughes063525c2014-05-13 11:19:57 -0700797#if defined(__BIONIC__)
798 ASSERT_EQ(offset_inside_mb, static_cast<off_t>(pos_inside_mb));
799#endif
Calin Juravle03e4ebe2014-05-08 14:42:06 +0100800
801 // Reading from within a byte should produce an error.
802 ASSERT_EQ(WEOF, fgetwc(fp));
803 ASSERT_EQ(EILSEQ, errno);
804
805 // Reverting to a valid position should work.
806 ASSERT_EQ(0, fsetpos(fp, &mb_two_bytes_pos));
807 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp)));
808
809 // Moving withing a multi byte with fsetpos should work but reading should
810 // produce an error.
811 ASSERT_EQ(0, fsetpos(fp, &pos_inside_mb));
812 ASSERT_EQ(WEOF, fgetwc(fp));
813 ASSERT_EQ(EILSEQ, errno);
814
815 fclose(fp);
816}
Elliott Hughes6b841db2014-08-20 16:10:49 -0700817
Christopher Ferris13f26a72016-01-13 13:47:58 -0800818TEST(STDIO_TEST, fmemopen) {
Elliott Hughes6b841db2014-08-20 16:10:49 -0700819 char buf[16];
820 memset(buf, 0, sizeof(buf));
821 FILE* fp = fmemopen(buf, sizeof(buf), "r+");
822 ASSERT_EQ('<', fputc('<', fp));
823 ASSERT_NE(EOF, fputs("abc>\n", fp));
824 fflush(fp);
825
826 ASSERT_STREQ("<abc>\n", buf);
827
Elliott Hughes70715da2016-08-01 16:35:17 -0700828 AssertFileIs(fp, "<abc>\n", true);
Elliott Hughes6b841db2014-08-20 16:10:49 -0700829 fclose(fp);
830}
831
Christopher Ferris13f26a72016-01-13 13:47:58 -0800832TEST(STDIO_TEST, fmemopen_NULL) {
Elliott Hughes6b841db2014-08-20 16:10:49 -0700833 FILE* fp = fmemopen(nullptr, 128, "r+");
834 ASSERT_NE(EOF, fputs("xyz\n", fp));
835
Elliott Hughes70715da2016-08-01 16:35:17 -0700836 AssertFileIs(fp, "xyz\n", true);
Elliott Hughes6b841db2014-08-20 16:10:49 -0700837 fclose(fp);
838}
839
Christopher Ferris13f26a72016-01-13 13:47:58 -0800840TEST(STDIO_TEST, fmemopen_EINVAL) {
Elliott Hughes6b841db2014-08-20 16:10:49 -0700841 char buf[16];
842
843 // Invalid size.
844 errno = 0;
845 ASSERT_EQ(nullptr, fmemopen(buf, 0, "r+"));
846 ASSERT_EQ(EINVAL, errno);
847
848 // No '+' with NULL buffer.
849 errno = 0;
850 ASSERT_EQ(nullptr, fmemopen(nullptr, 0, "r"));
851 ASSERT_EQ(EINVAL, errno);
852}
853
Christopher Ferris13f26a72016-01-13 13:47:58 -0800854TEST(STDIO_TEST, open_memstream) {
Elliott Hughes6b841db2014-08-20 16:10:49 -0700855 char* p = nullptr;
856 size_t size = 0;
857 FILE* fp = open_memstream(&p, &size);
858 ASSERT_NE(EOF, fputs("hello, world!", fp));
859 fclose(fp);
860
861 ASSERT_STREQ("hello, world!", p);
862 ASSERT_EQ(strlen("hello, world!"), size);
863 free(p);
864}
865
Christopher Ferris13f26a72016-01-13 13:47:58 -0800866TEST(STDIO_TEST, open_memstream_EINVAL) {
Elliott Hughes6b841db2014-08-20 16:10:49 -0700867#if defined(__BIONIC__)
868 char* p;
869 size_t size;
870
871 // Invalid buffer.
872 errno = 0;
873 ASSERT_EQ(nullptr, open_memstream(nullptr, &size));
874 ASSERT_EQ(EINVAL, errno);
875
876 // Invalid size.
877 errno = 0;
878 ASSERT_EQ(nullptr, open_memstream(&p, nullptr));
879 ASSERT_EQ(EINVAL, errno);
880#else
Elliott Hughes9677fab2016-01-25 15:50:59 -0800881 GTEST_LOG_(INFO) << "This test does nothing on glibc.\n";
Elliott Hughes6b841db2014-08-20 16:10:49 -0700882#endif
883}
Elliott Hughes31165ed2014-09-23 17:34:29 -0700884
Christopher Ferris13f26a72016-01-13 13:47:58 -0800885TEST(STDIO_TEST, fdopen_CLOEXEC) {
Elliott Hughes31165ed2014-09-23 17:34:29 -0700886 int fd = open("/proc/version", O_RDONLY);
887 ASSERT_TRUE(fd != -1);
888
889 // This fd doesn't have O_CLOEXEC...
890 int flags = fcntl(fd, F_GETFD);
891 ASSERT_TRUE(flags != -1);
892 ASSERT_EQ(0, flags & FD_CLOEXEC);
893
894 FILE* fp = fdopen(fd, "re");
895 ASSERT_TRUE(fp != NULL);
896
897 // ...but the new one does.
898 flags = fcntl(fileno(fp), F_GETFD);
899 ASSERT_TRUE(flags != -1);
900 ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
901
902 fclose(fp);
903 close(fd);
904}
905
Christopher Ferris13f26a72016-01-13 13:47:58 -0800906TEST(STDIO_TEST, freopen_CLOEXEC) {
Elliott Hughes31165ed2014-09-23 17:34:29 -0700907 FILE* fp = fopen("/proc/version", "r");
908 ASSERT_TRUE(fp != NULL);
909
910 // This FILE* doesn't have O_CLOEXEC...
911 int flags = fcntl(fileno(fp), F_GETFD);
912 ASSERT_TRUE(flags != -1);
913 ASSERT_EQ(0, flags & FD_CLOEXEC);
914
915 fp = freopen("/proc/version", "re", fp);
916
917 // ...but the new one does.
918 flags = fcntl(fileno(fp), F_GETFD);
919 ASSERT_TRUE(flags != -1);
920 ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
921
922 fclose(fp);
923}
Elliott Hughes20841a12014-12-01 16:13:30 -0800924
Elliott Hughesf226ee52016-02-03 11:24:28 -0800925TEST(STDIO_TEST, fopen64_freopen64) {
926 FILE* fp = fopen64("/proc/version", "r");
927 ASSERT_TRUE(fp != nullptr);
928 fp = freopen64("/proc/version", "re", fp);
929 ASSERT_TRUE(fp != nullptr);
930 fclose(fp);
931}
932
Elliott Hughes20841a12014-12-01 16:13:30 -0800933// https://code.google.com/p/android/issues/detail?id=81155
934// http://b/18556607
Christopher Ferris13f26a72016-01-13 13:47:58 -0800935TEST(STDIO_TEST, fread_unbuffered_pathological_performance) {
Elliott Hughes20841a12014-12-01 16:13:30 -0800936 FILE* fp = fopen("/dev/zero", "r");
937 ASSERT_TRUE(fp != NULL);
938
939 // Make this stream unbuffered.
940 setvbuf(fp, 0, _IONBF, 0);
941
942 char buf[65*1024];
943 memset(buf, 0xff, sizeof(buf));
944
945 time_t t0 = time(NULL);
946 for (size_t i = 0; i < 1024; ++i) {
Elliott Hughese6bb5a22015-01-23 17:48:15 -0800947 ASSERT_EQ(1U, fread(buf, 64*1024, 1, fp));
Elliott Hughes20841a12014-12-01 16:13:30 -0800948 }
949 time_t t1 = time(NULL);
950
951 fclose(fp);
952
953 // 1024 64KiB reads should have been very quick.
954 ASSERT_LE(t1 - t0, 1);
955
956 for (size_t i = 0; i < 64*1024; ++i) {
957 ASSERT_EQ('\0', buf[i]);
958 }
959 for (size_t i = 64*1024; i < 65*1024; ++i) {
960 ASSERT_EQ('\xff', buf[i]);
961 }
962}
Elliott Hughes75b99382015-01-20 11:23:50 -0800963
Christopher Ferris13f26a72016-01-13 13:47:58 -0800964TEST(STDIO_TEST, fread_EOF) {
Elliott Hughes0ed7e082015-01-22 15:13:38 -0800965 std::string digits("0123456789");
966 FILE* fp = fmemopen(&digits[0], digits.size(), "r");
Elliott Hughes75b99382015-01-20 11:23:50 -0800967
968 // Try to read too much, but little enough that it still fits in the FILE's internal buffer.
969 char buf1[4 * 4];
970 memset(buf1, 0, sizeof(buf1));
971 ASSERT_EQ(2U, fread(buf1, 4, 4, fp));
Elliott Hughes0ed7e082015-01-22 15:13:38 -0800972 ASSERT_STREQ("0123456789", buf1);
Elliott Hughes75b99382015-01-20 11:23:50 -0800973 ASSERT_TRUE(feof(fp));
974
975 rewind(fp);
976
Elliott Hughes0ed7e082015-01-22 15:13:38 -0800977 // Try to read way too much so stdio tries to read more direct from the stream.
978 char buf2[4 * 4096];
Elliott Hughes75b99382015-01-20 11:23:50 -0800979 memset(buf2, 0, sizeof(buf2));
980 ASSERT_EQ(2U, fread(buf2, 4, 4096, fp));
Elliott Hughes0ed7e082015-01-22 15:13:38 -0800981 ASSERT_STREQ("0123456789", buf2);
Elliott Hughes75b99382015-01-20 11:23:50 -0800982 ASSERT_TRUE(feof(fp));
983
984 fclose(fp);
985}
Elliott Hughese6bb5a22015-01-23 17:48:15 -0800986
987static void test_fread_from_write_only_stream(size_t n) {
988 FILE* fp = fopen("/dev/null", "w");
989 std::vector<char> buf(n, 0);
990 errno = 0;
991 ASSERT_EQ(0U, fread(&buf[0], n, 1, fp));
992 ASSERT_EQ(EBADF, errno);
993 ASSERT_TRUE(ferror(fp));
994 ASSERT_FALSE(feof(fp));
995 fclose(fp);
996}
997
Christopher Ferris13f26a72016-01-13 13:47:58 -0800998TEST(STDIO_TEST, fread_from_write_only_stream_slow_path) {
Elliott Hughese6bb5a22015-01-23 17:48:15 -0800999 test_fread_from_write_only_stream(1);
1000}
1001
Christopher Ferris13f26a72016-01-13 13:47:58 -08001002TEST(STDIO_TEST, fread_from_write_only_stream_fast_path) {
Elliott Hughese6bb5a22015-01-23 17:48:15 -08001003 test_fread_from_write_only_stream(64*1024);
1004}
1005
1006static void test_fwrite_after_fread(size_t n) {
1007 TemporaryFile tf;
1008
1009 FILE* fp = fdopen(tf.fd, "w+");
1010 ASSERT_EQ(1U, fwrite("1", 1, 1, fp));
1011 fflush(fp);
1012
1013 // We've flushed but not rewound, so there's nothing to read.
1014 std::vector<char> buf(n, 0);
1015 ASSERT_EQ(0U, fread(&buf[0], 1, buf.size(), fp));
1016 ASSERT_TRUE(feof(fp));
1017
1018 // But hitting EOF doesn't prevent us from writing...
1019 errno = 0;
Elliott Hughes9677fab2016-01-25 15:50:59 -08001020 ASSERT_EQ(1U, fwrite("2", 1, 1, fp)) << strerror(errno);
Elliott Hughese6bb5a22015-01-23 17:48:15 -08001021
1022 // And if we rewind, everything's there.
1023 rewind(fp);
1024 ASSERT_EQ(2U, fread(&buf[0], 1, buf.size(), fp));
1025 ASSERT_EQ('1', buf[0]);
1026 ASSERT_EQ('2', buf[1]);
1027
1028 fclose(fp);
1029}
1030
Christopher Ferris13f26a72016-01-13 13:47:58 -08001031TEST(STDIO_TEST, fwrite_after_fread_slow_path) {
Elliott Hughese6bb5a22015-01-23 17:48:15 -08001032 test_fwrite_after_fread(16);
1033}
1034
Christopher Ferris13f26a72016-01-13 13:47:58 -08001035TEST(STDIO_TEST, fwrite_after_fread_fast_path) {
Elliott Hughese6bb5a22015-01-23 17:48:15 -08001036 test_fwrite_after_fread(64*1024);
1037}
Christopher Ferriscc9ca102015-02-27 18:22:45 -08001038
1039// http://b/19172514
Christopher Ferris13f26a72016-01-13 13:47:58 -08001040TEST(STDIO_TEST, fread_after_fseek) {
Christopher Ferriscc9ca102015-02-27 18:22:45 -08001041 TemporaryFile tf;
1042
1043 FILE* fp = fopen(tf.filename, "w+");
1044 ASSERT_TRUE(fp != nullptr);
1045
1046 char file_data[12288];
1047 for (size_t i = 0; i < 12288; i++) {
1048 file_data[i] = i;
1049 }
1050 ASSERT_EQ(12288U, fwrite(file_data, 1, 12288, fp));
1051 fclose(fp);
1052
1053 fp = fopen(tf.filename, "r");
1054 ASSERT_TRUE(fp != nullptr);
1055
1056 char buffer[8192];
1057 size_t cur_location = 0;
1058 // Small read to populate internal buffer.
1059 ASSERT_EQ(100U, fread(buffer, 1, 100, fp));
1060 ASSERT_EQ(memcmp(file_data, buffer, 100), 0);
1061
1062 cur_location = static_cast<size_t>(ftell(fp));
1063 // Large read to force reading into the user supplied buffer and bypassing
1064 // the internal buffer.
1065 ASSERT_EQ(8192U, fread(buffer, 1, 8192, fp));
1066 ASSERT_EQ(memcmp(file_data+cur_location, buffer, 8192), 0);
1067
1068 // Small backwards seek to verify fseek does not reuse the internal buffer.
Elliott Hughes9677fab2016-01-25 15:50:59 -08001069 ASSERT_EQ(0, fseek(fp, -22, SEEK_CUR)) << strerror(errno);
Christopher Ferriscc9ca102015-02-27 18:22:45 -08001070 cur_location = static_cast<size_t>(ftell(fp));
1071 ASSERT_EQ(22U, fread(buffer, 1, 22, fp));
1072 ASSERT_EQ(memcmp(file_data+cur_location, buffer, 22), 0);
1073
1074 fclose(fp);
1075}
Elliott Hughes8ab433d2015-10-09 17:57:26 -07001076
1077// https://code.google.com/p/android/issues/detail?id=184847
Christopher Ferris13f26a72016-01-13 13:47:58 -08001078TEST(STDIO_TEST, fread_EOF_184847) {
Elliott Hughes8ab433d2015-10-09 17:57:26 -07001079 TemporaryFile tf;
1080 char buf[6] = {0};
1081
1082 FILE* fw = fopen(tf.filename, "w");
1083 ASSERT_TRUE(fw != nullptr);
1084
1085 FILE* fr = fopen(tf.filename, "r");
1086 ASSERT_TRUE(fr != nullptr);
1087
1088 fwrite("a", 1, 1, fw);
1089 fflush(fw);
1090 ASSERT_EQ(1U, fread(buf, 1, 1, fr));
1091 ASSERT_STREQ("a", buf);
1092
1093 // 'fr' is now at EOF.
1094 ASSERT_EQ(0U, fread(buf, 1, 1, fr));
1095 ASSERT_TRUE(feof(fr));
1096
1097 // Write some more...
1098 fwrite("z", 1, 1, fw);
1099 fflush(fw);
1100
1101 // ...and check that we can read it back.
1102 // (BSD thinks that once a stream has hit EOF, it must always return EOF. SysV disagrees.)
1103 ASSERT_EQ(1U, fread(buf, 1, 1, fr));
1104 ASSERT_STREQ("z", buf);
1105
1106 // But now we're done.
1107 ASSERT_EQ(0U, fread(buf, 1, 1, fr));
1108
1109 fclose(fr);
1110 fclose(fw);
1111}
Elliott Hughes923f1652016-01-19 15:46:05 -08001112
1113TEST(STDIO_TEST, fclose_invalidates_fd) {
1114 // The typical error we're trying to help people catch involves accessing
1115 // memory after it's been freed. But we know that stdin/stdout/stderr are
1116 // special and don't get deallocated, so this test uses stdin.
1117 ASSERT_EQ(0, fclose(stdin));
1118
1119 // Even though using a FILE* after close is undefined behavior, I've closed
1120 // this bug as "WAI" too many times. We shouldn't hand out stale fds,
1121 // especially because they might actually correspond to a real stream.
1122 errno = 0;
1123 ASSERT_EQ(-1, fileno(stdin));
1124 ASSERT_EQ(EBADF, errno);
1125}
Elliott Hughes2704bd12016-01-20 17:14:53 -08001126
1127TEST(STDIO_TEST, fseek_ftell_unseekable) {
1128#if defined(__BIONIC__) // glibc has fopencookie instead.
1129 auto read_fn = [](void*, char*, int) { return -1; };
1130 FILE* fp = funopen(nullptr, read_fn, nullptr, nullptr, nullptr);
1131 ASSERT_TRUE(fp != nullptr);
1132
1133 // Check that ftell balks on an unseekable FILE*.
1134 errno = 0;
1135 ASSERT_EQ(-1, ftell(fp));
1136 ASSERT_EQ(ESPIPE, errno);
1137
1138 // SEEK_CUR is rewritten as SEEK_SET internally...
1139 errno = 0;
1140 ASSERT_EQ(-1, fseek(fp, 0, SEEK_CUR));
1141 ASSERT_EQ(ESPIPE, errno);
1142
1143 // ...so it's worth testing the direct seek path too.
1144 errno = 0;
1145 ASSERT_EQ(-1, fseek(fp, 0, SEEK_SET));
1146 ASSERT_EQ(ESPIPE, errno);
1147
1148 fclose(fp);
Elliott Hughes03e65eb2016-01-26 14:13:04 -08001149#else
1150 GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
1151#endif
1152}
1153
1154TEST(STDIO_TEST, funopen_EINVAL) {
1155#if defined(__BIONIC__)
1156 errno = 0;
1157 ASSERT_EQ(nullptr, funopen(nullptr, nullptr, nullptr, nullptr, nullptr));
1158 ASSERT_EQ(EINVAL, errno);
1159#else
1160 GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
1161#endif
1162}
1163
1164TEST(STDIO_TEST, funopen_seek) {
1165#if defined(__BIONIC__)
1166 auto read_fn = [](void*, char*, int) { return -1; };
1167
1168 auto seek_fn = [](void*, fpos_t, int) -> fpos_t { return 0xfedcba12; };
1169 auto seek64_fn = [](void*, fpos64_t, int) -> fpos64_t { return 0xfedcba12345678; };
1170
1171 FILE* fp = funopen(nullptr, read_fn, nullptr, seek_fn, nullptr);
1172 ASSERT_TRUE(fp != nullptr);
1173 fpos_t pos;
Elliott Hughes955426e2016-01-26 18:25:52 -08001174#if defined(__LP64__)
1175 EXPECT_EQ(0, fgetpos(fp, &pos)) << strerror(errno);
1176 EXPECT_EQ(0xfedcba12LL, pos);
1177#else
1178 EXPECT_EQ(-1, fgetpos(fp, &pos)) << strerror(errno);
1179 EXPECT_EQ(EOVERFLOW, errno);
1180#endif
Elliott Hughes03e65eb2016-01-26 14:13:04 -08001181
1182 FILE* fp64 = funopen64(nullptr, read_fn, nullptr, seek64_fn, nullptr);
1183 ASSERT_TRUE(fp64 != nullptr);
1184 fpos64_t pos64;
Elliott Hughes955426e2016-01-26 18:25:52 -08001185 EXPECT_EQ(0, fgetpos64(fp64, &pos64)) << strerror(errno);
1186 EXPECT_EQ(0xfedcba12345678, pos64);
Elliott Hughes03e65eb2016-01-26 14:13:04 -08001187#else
1188 GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n";
Elliott Hughes2704bd12016-01-20 17:14:53 -08001189#endif
1190}
Elliott Hughes71288cb2016-01-22 19:22:44 -08001191
1192TEST(STDIO_TEST, lots_of_concurrent_files) {
1193 std::vector<TemporaryFile*> tfs;
1194 std::vector<FILE*> fps;
1195
1196 for (size_t i = 0; i < 256; ++i) {
1197 TemporaryFile* tf = new TemporaryFile;
1198 tfs.push_back(tf);
1199 FILE* fp = fopen(tf->filename, "w+");
1200 fps.push_back(fp);
1201 fprintf(fp, "hello %zu!\n", i);
1202 fflush(fp);
1203 }
1204
1205 for (size_t i = 0; i < 256; ++i) {
Elliott Hughes71288cb2016-01-22 19:22:44 -08001206 char expected[BUFSIZ];
1207 snprintf(expected, sizeof(expected), "hello %zu!\n", i);
Elliott Hughes71288cb2016-01-22 19:22:44 -08001208
Elliott Hughes70715da2016-08-01 16:35:17 -07001209 AssertFileIs(fps[i], expected);
Elliott Hughes71288cb2016-01-22 19:22:44 -08001210 fclose(fps[i]);
1211 delete tfs[i];
1212 }
1213}
Elliott Hughes9677fab2016-01-25 15:50:59 -08001214
1215static void AssertFileOffsetAt(FILE* fp, off64_t offset) {
1216 EXPECT_EQ(offset, ftell(fp));
1217 EXPECT_EQ(offset, ftello(fp));
Elliott Hughese4fa6e92016-02-02 22:39:15 -08001218 EXPECT_EQ(offset, ftello64(fp));
Elliott Hughes9677fab2016-01-25 15:50:59 -08001219 fpos_t pos;
1220 fpos64_t pos64;
1221 EXPECT_EQ(0, fgetpos(fp, &pos));
1222 EXPECT_EQ(0, fgetpos64(fp, &pos64));
1223#if defined(__BIONIC__)
1224 EXPECT_EQ(offset, static_cast<off64_t>(pos));
1225 EXPECT_EQ(offset, static_cast<off64_t>(pos64));
1226#else
1227 GTEST_LOG_(INFO) << "glibc's fpos_t is opaque.\n";
1228#endif
1229}
1230
1231TEST(STDIO_TEST, seek_tell_family_smoke) {
1232 TemporaryFile tf;
1233 FILE* fp = fdopen(tf.fd, "w+");
1234
1235 // Initially we should be at 0.
1236 AssertFileOffsetAt(fp, 0);
1237
1238 // Seek to offset 8192.
1239 ASSERT_EQ(0, fseek(fp, 8192, SEEK_SET));
1240 AssertFileOffsetAt(fp, 8192);
1241 fpos_t eight_k_pos;
1242 ASSERT_EQ(0, fgetpos(fp, &eight_k_pos));
1243
1244 // Seek forward another 8192...
1245 ASSERT_EQ(0, fseek(fp, 8192, SEEK_CUR));
1246 AssertFileOffsetAt(fp, 8192 + 8192);
1247 fpos64_t sixteen_k_pos64;
1248 ASSERT_EQ(0, fgetpos64(fp, &sixteen_k_pos64));
1249
1250 // Seek back 8192...
1251 ASSERT_EQ(0, fseek(fp, -8192, SEEK_CUR));
1252 AssertFileOffsetAt(fp, 8192);
1253
1254 // Since we haven't written anything, the end is also at 0.
1255 ASSERT_EQ(0, fseek(fp, 0, SEEK_END));
1256 AssertFileOffsetAt(fp, 0);
1257
1258 // Check that our fpos64_t from 16KiB works...
1259 ASSERT_EQ(0, fsetpos64(fp, &sixteen_k_pos64));
1260 AssertFileOffsetAt(fp, 8192 + 8192);
1261 // ...as does our fpos_t from 8192.
1262 ASSERT_EQ(0, fsetpos(fp, &eight_k_pos));
1263 AssertFileOffsetAt(fp, 8192);
1264
1265 // Do fseeko and fseeko64 work too?
1266 ASSERT_EQ(0, fseeko(fp, 1234, SEEK_SET));
1267 AssertFileOffsetAt(fp, 1234);
1268 ASSERT_EQ(0, fseeko64(fp, 5678, SEEK_SET));
1269 AssertFileOffsetAt(fp, 5678);
1270
1271 fclose(fp);
1272}
1273
1274TEST(STDIO_TEST, fseek_fseeko_EINVAL) {
1275 TemporaryFile tf;
1276 FILE* fp = fdopen(tf.fd, "w+");
1277
1278 // Bad whence.
1279 errno = 0;
1280 ASSERT_EQ(-1, fseek(fp, 0, 123));
1281 ASSERT_EQ(EINVAL, errno);
1282 errno = 0;
1283 ASSERT_EQ(-1, fseeko(fp, 0, 123));
1284 ASSERT_EQ(EINVAL, errno);
1285 errno = 0;
1286 ASSERT_EQ(-1, fseeko64(fp, 0, 123));
1287 ASSERT_EQ(EINVAL, errno);
1288
1289 // Bad offset.
1290 errno = 0;
1291 ASSERT_EQ(-1, fseek(fp, -1, SEEK_SET));
1292 ASSERT_EQ(EINVAL, errno);
1293 errno = 0;
1294 ASSERT_EQ(-1, fseeko(fp, -1, SEEK_SET));
1295 ASSERT_EQ(EINVAL, errno);
1296 errno = 0;
1297 ASSERT_EQ(-1, fseeko64(fp, -1, SEEK_SET));
1298 ASSERT_EQ(EINVAL, errno);
1299
1300 fclose(fp);
1301}
Elliott Hughes20788ae2016-06-09 15:16:32 -07001302
1303TEST(STDIO_TEST, ctermid) {
1304 ASSERT_STREQ("/dev/tty", ctermid(nullptr));
1305
1306 char buf[L_ctermid] = {};
1307 ASSERT_EQ(buf, ctermid(buf));
1308 ASSERT_STREQ("/dev/tty", buf);
1309}
Elliott Hughesd1f25a72016-08-05 15:53:03 -07001310
1311TEST(STDIO_TEST, remove) {
1312 struct stat sb;
1313
1314 TemporaryFile tf;
1315 ASSERT_EQ(0, remove(tf.filename));
1316 ASSERT_EQ(-1, lstat(tf.filename, &sb));
1317 ASSERT_EQ(ENOENT, errno);
1318
1319 TemporaryDir td;
1320 ASSERT_EQ(0, remove(td.dirname));
1321 ASSERT_EQ(-1, lstat(td.dirname, &sb));
1322 ASSERT_EQ(ENOENT, errno);
1323
1324 errno = 0;
1325 ASSERT_EQ(-1, remove(tf.filename));
1326 ASSERT_EQ(ENOENT, errno);
1327
1328 errno = 0;
1329 ASSERT_EQ(-1, remove(td.dirname));
1330 ASSERT_EQ(ENOENT, errno);
1331}