blob: 3194e59e9cc3367a7ffee9d8b846efb7ddca911a [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
30#include "TemporaryFile.h"
Elliott Hughes91875dc2012-09-24 17:55:15 -070031
32TEST(stdio, tmpfile_fileno_fprintf_rewind_fgets) {
33 FILE* fp = tmpfile();
34 ASSERT_TRUE(fp != NULL);
35
36 int fd = fileno(fp);
37 ASSERT_NE(fd, -1);
38
39 struct stat sb;
40 int rc = fstat(fd, &sb);
41 ASSERT_NE(rc, -1);
42 ASSERT_EQ(sb.st_mode & 0777, 0600U);
43
44 rc = fprintf(fp, "hello\n");
45 ASSERT_EQ(rc, 6);
46
47 rewind(fp);
48
49 char buf[16];
50 char* s = fgets(buf, sizeof(buf), fp);
51 ASSERT_TRUE(s != NULL);
52 ASSERT_STREQ("hello\n", s);
53
54 fclose(fp);
55}
Irina Tirdeaeac9eb42012-09-08 09:28:30 +030056
57TEST(stdio, getdelim) {
58 FILE* fp = tmpfile();
59 ASSERT_TRUE(fp != NULL);
60
61 const char* line_written = "This is a test";
62 int rc = fprintf(fp, "%s", line_written);
63 ASSERT_EQ(rc, static_cast<int>(strlen(line_written)));
64
65 rewind(fp);
66
67 char* word_read = NULL;
68 size_t allocated_length = 0;
69
70 const char* expected[] = { "This ", " ", "is ", "a ", "test" };
71 for (size_t i = 0; i < 5; ++i) {
72 ASSERT_FALSE(feof(fp));
73 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), static_cast<int>(strlen(expected[i])));
74 ASSERT_GE(allocated_length, strlen(expected[i]));
75 ASSERT_STREQ(word_read, expected[i]);
76 }
77 // The last read should have set the end-of-file indicator for the stream.
78 ASSERT_TRUE(feof(fp));
79 clearerr(fp);
80
81 // getdelim returns -1 but doesn't set errno if we're already at EOF.
82 // It should set the end-of-file indicator for the stream, though.
83 errno = 0;
84 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -080085 ASSERT_EQ(0, errno);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +030086 ASSERT_TRUE(feof(fp));
87
88 free(word_read);
89 fclose(fp);
90}
91
92TEST(stdio, getdelim_invalid) {
93 FILE* fp = tmpfile();
Elliott Hughes6ad8f762013-12-19 14:56:17 -080094 ASSERT_TRUE(fp != NULL);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +030095
96 char* buffer = NULL;
97 size_t buffer_length = 0;
98
99 // The first argument can't be NULL.
100 errno = 0;
101 ASSERT_EQ(getdelim(NULL, &buffer_length, ' ', fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800102 ASSERT_EQ(EINVAL, errno);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300103
104 // The second argument can't be NULL.
105 errno = 0;
106 ASSERT_EQ(getdelim(&buffer, NULL, ' ', fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800107 ASSERT_EQ(EINVAL, errno);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300108
Elliott Hughes20f8aec2014-05-12 15:15:37 -0700109 // The underlying fd can't be closed.
110 ASSERT_EQ(0, close(fileno(fp)));
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300111 errno = 0;
112 ASSERT_EQ(getdelim(&buffer, &buffer_length, ' ', fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800113 ASSERT_EQ(EBADF, errno);
Elliott Hughes20f8aec2014-05-12 15:15:37 -0700114 fclose(fp);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300115}
116
117TEST(stdio, getline) {
118 FILE* fp = tmpfile();
119 ASSERT_TRUE(fp != NULL);
120
121 const char* line_written = "This is a test for getline\n";
122 const size_t line_count = 5;
123
124 for (size_t i = 0; i < line_count; ++i) {
125 int rc = fprintf(fp, "%s", line_written);
126 ASSERT_EQ(rc, static_cast<int>(strlen(line_written)));
127 }
128
129 rewind(fp);
130
131 char* line_read = NULL;
132 size_t allocated_length = 0;
133
134 size_t read_line_count = 0;
135 ssize_t read_char_count;
136 while ((read_char_count = getline(&line_read, &allocated_length, fp)) != -1) {
137 ASSERT_EQ(read_char_count, static_cast<int>(strlen(line_written)));
138 ASSERT_GE(allocated_length, strlen(line_written));
139 ASSERT_STREQ(line_read, line_written);
140 ++read_line_count;
141 }
142 ASSERT_EQ(read_line_count, line_count);
143
144 // The last read should have set the end-of-file indicator for the stream.
145 ASSERT_TRUE(feof(fp));
146 clearerr(fp);
147
148 // getline returns -1 but doesn't set errno if we're already at EOF.
149 // It should set the end-of-file indicator for the stream, though.
150 errno = 0;
151 ASSERT_EQ(getline(&line_read, &allocated_length, fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800152 ASSERT_EQ(0, errno);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300153 ASSERT_TRUE(feof(fp));
154
155 free(line_read);
156 fclose(fp);
157}
158
159TEST(stdio, getline_invalid) {
160 FILE* fp = tmpfile();
Elliott Hughes6ad8f762013-12-19 14:56:17 -0800161 ASSERT_TRUE(fp != NULL);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300162
163 char* buffer = NULL;
164 size_t buffer_length = 0;
165
166 // The first argument can't be NULL.
167 errno = 0;
168 ASSERT_EQ(getline(NULL, &buffer_length, fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800169 ASSERT_EQ(EINVAL, errno);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300170
171 // The second argument can't be NULL.
172 errno = 0;
173 ASSERT_EQ(getline(&buffer, NULL, fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800174 ASSERT_EQ(EINVAL, errno);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300175
Elliott Hughes20f8aec2014-05-12 15:15:37 -0700176 // The underlying fd can't be closed.
177 ASSERT_EQ(0, close(fileno(fp)));
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300178 errno = 0;
179 ASSERT_EQ(getline(&buffer, &buffer_length, fp), -1);
Elliott Hughes5e3fc432013-02-11 16:36:48 -0800180 ASSERT_EQ(EBADF, errno);
Elliott Hughes20f8aec2014-05-12 15:15:37 -0700181 fclose(fp);
Irina Tirdeaeac9eb42012-09-08 09:28:30 +0300182}
Thorsten Glaserc641caf2013-02-17 16:50:58 +0000183
184TEST(stdio, printf_ssize_t) {
Elliott Hughese2556422013-02-28 10:51:14 -0800185 // http://b/8253769
Elliott Hughese2556422013-02-28 10:51:14 -0800186 ASSERT_EQ(sizeof(ssize_t), sizeof(long int));
Elliott Hughesb6e22482013-03-08 15:28:52 -0800187 ASSERT_EQ(sizeof(ssize_t), sizeof(size_t));
188 // For our 32-bit ABI, we had a ssize_t definition that confuses GCC into saying:
Thorsten Glaserc641caf2013-02-17 16:50:58 +0000189 // error: format '%zd' expects argument of type 'signed size_t',
190 // but argument 4 has type 'ssize_t {aka long int}' [-Werror=format]
191 ssize_t v = 1;
192 char buf[32];
193 snprintf(buf, sizeof(buf), "%zd", v);
194}
Elliott Hughes6b3f49a2013-03-06 16:20:55 -0800195
Elliott Hughes05493712014-04-17 17:30:03 -0700196// https://code.google.com/p/android/issues/detail?id=64886
197TEST(stdio, snprintf_a) {
198 char buf[BUFSIZ];
199 EXPECT_EQ(23, snprintf(buf, sizeof(buf), "<%a>", 9990.235));
200 EXPECT_STREQ("<0x1.3831e147ae148p+13>", buf);
201}
202
203TEST(stdio, snprintf_lc) {
204 char buf[BUFSIZ];
205 wint_t wc = L'a';
206 EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%lc>", wc));
207 EXPECT_STREQ("<a>", buf);
208}
209
210TEST(stdio, snprintf_ls) {
211 char buf[BUFSIZ];
212 wchar_t* ws = NULL;
213 EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%ls>", ws));
214 EXPECT_STREQ("<(null)>", buf);
215
216 wchar_t chars[] = { L'h', L'i', 0 };
217 ws = chars;
218 EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%ls>", ws));
219 EXPECT_STREQ("<hi>", buf);
220}
221
222TEST(stdio, snprintf_n) {
Elliott Hughes063525c2014-05-13 11:19:57 -0700223#if defined(__BIONIC__)
Elliott Hughese2341d02014-05-02 18:16:32 -0700224 // http://b/14492135
Elliott Hughes7248a2d2013-09-24 18:01:33 -0700225 char buf[32];
Elliott Hughese2341d02014-05-02 18:16:32 -0700226 int i = 1234;
227 EXPECT_EQ(5, snprintf(buf, sizeof(buf), "a %n b", &i));
228 EXPECT_EQ(1234, i);
229 EXPECT_STREQ("a n b", buf);
230#else
231 GTEST_LOG_(INFO) << "This test does nothing.\n";
232#endif
Elliott Hughes7248a2d2013-09-24 18:01:33 -0700233}
Elliott Hughes7248a2d2013-09-24 18:01:33 -0700234
Elliott Hughes1d13c642013-09-23 16:02:39 -0700235TEST(stdio, snprintf_smoke) {
236 char buf[BUFSIZ];
237
238 snprintf(buf, sizeof(buf), "a");
239 EXPECT_STREQ("a", buf);
240
241 snprintf(buf, sizeof(buf), "%%");
242 EXPECT_STREQ("%", buf);
243
244 snprintf(buf, sizeof(buf), "01234");
245 EXPECT_STREQ("01234", buf);
246
247 snprintf(buf, sizeof(buf), "a%sb", "01234");
248 EXPECT_STREQ("a01234b", buf);
249
250 char* s = NULL;
251 snprintf(buf, sizeof(buf), "a%sb", s);
252 EXPECT_STREQ("a(null)b", buf);
253
254 snprintf(buf, sizeof(buf), "aa%scc", "bb");
255 EXPECT_STREQ("aabbcc", buf);
256
257 snprintf(buf, sizeof(buf), "a%cc", 'b');
258 EXPECT_STREQ("abc", buf);
259
260 snprintf(buf, sizeof(buf), "a%db", 1234);
261 EXPECT_STREQ("a1234b", buf);
262
263 snprintf(buf, sizeof(buf), "a%db", -8123);
264 EXPECT_STREQ("a-8123b", buf);
265
Stephen Hines6c7b3cb2013-10-11 16:03:21 -0700266 snprintf(buf, sizeof(buf), "a%hdb", static_cast<short>(0x7fff0010));
Elliott Hughes1d13c642013-09-23 16:02:39 -0700267 EXPECT_STREQ("a16b", buf);
268
Stephen Hines6c7b3cb2013-10-11 16:03:21 -0700269 snprintf(buf, sizeof(buf), "a%hhdb", static_cast<char>(0x7fffff10));
Elliott Hughes1d13c642013-09-23 16:02:39 -0700270 EXPECT_STREQ("a16b", buf);
271
272 snprintf(buf, sizeof(buf), "a%lldb", 0x1000000000LL);
273 EXPECT_STREQ("a68719476736b", buf);
274
275 snprintf(buf, sizeof(buf), "a%ldb", 70000L);
276 EXPECT_STREQ("a70000b", buf);
277
278 snprintf(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234));
279 EXPECT_STREQ("a0xb0001234b", buf);
280
281 snprintf(buf, sizeof(buf), "a%xz", 0x12ab);
282 EXPECT_STREQ("a12abz", buf);
283
284 snprintf(buf, sizeof(buf), "a%Xz", 0x12ab);
285 EXPECT_STREQ("a12ABz", buf);
286
287 snprintf(buf, sizeof(buf), "a%08xz", 0x123456);
288 EXPECT_STREQ("a00123456z", buf);
289
290 snprintf(buf, sizeof(buf), "a%5dz", 1234);
291 EXPECT_STREQ("a 1234z", buf);
292
293 snprintf(buf, sizeof(buf), "a%05dz", 1234);
294 EXPECT_STREQ("a01234z", buf);
295
296 snprintf(buf, sizeof(buf), "a%8dz", 1234);
297 EXPECT_STREQ("a 1234z", buf);
298
299 snprintf(buf, sizeof(buf), "a%-8dz", 1234);
300 EXPECT_STREQ("a1234 z", buf);
301
302 snprintf(buf, sizeof(buf), "A%-11sZ", "abcdef");
303 EXPECT_STREQ("Aabcdef Z", buf);
304
305 snprintf(buf, sizeof(buf), "A%s:%dZ", "hello", 1234);
306 EXPECT_STREQ("Ahello:1234Z", buf);
307
308 snprintf(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5);
309 EXPECT_STREQ("a005:5:05z", buf);
310
311 void* p = NULL;
312 snprintf(buf, sizeof(buf), "a%d,%pz", 5, p);
Christopher Ferris13613132013-10-28 15:24:04 -0700313#if defined(__BIONIC__)
Elliott Hughes1d13c642013-09-23 16:02:39 -0700314 EXPECT_STREQ("a5,0x0z", buf);
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800315#else // __BIONIC__
Christopher Ferris13613132013-10-28 15:24:04 -0700316 EXPECT_STREQ("a5,(nil)z", buf);
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800317#endif // __BIONIC__
Elliott Hughes1d13c642013-09-23 16:02:39 -0700318
319 snprintf(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8);
320 EXPECT_STREQ("a68719476736,6,7,8z", buf);
321
322 snprintf(buf, sizeof(buf), "a_%f_b", 1.23f);
323 EXPECT_STREQ("a_1.230000_b", buf);
324
Stephen Hines6c7b3cb2013-10-11 16:03:21 -0700325 snprintf(buf, sizeof(buf), "a_%g_b", 3.14);
Elliott Hughes1d13c642013-09-23 16:02:39 -0700326 EXPECT_STREQ("a_3.14_b", buf);
Alexander Ivchenkoedd7c2e2014-04-01 17:01:39 +0400327
328 snprintf(buf, sizeof(buf), "%1$s %1$s", "print_me_twice");
329 EXPECT_STREQ("print_me_twice print_me_twice", buf);
Elliott Hughes1d13c642013-09-23 16:02:39 -0700330}
331
Elliott Hughes7823f322014-04-14 12:11:28 -0700332TEST(stdio, snprintf_f_special) {
333 char buf[BUFSIZ];
334 snprintf(buf, sizeof(buf), "%f", nanf(""));
Elliott Hughes4bd97ce2014-04-10 17:48:14 -0700335 EXPECT_STRCASEEQ("NaN", buf);
Elliott Hughes7823f322014-04-14 12:11:28 -0700336
337 snprintf(buf, sizeof(buf), "%f", HUGE_VALF);
Elliott Hughes4bd97ce2014-04-10 17:48:14 -0700338 EXPECT_STRCASEEQ("Inf", buf);
Elliott Hughes7823f322014-04-14 12:11:28 -0700339}
340
341TEST(stdio, snprintf_g_special) {
342 char buf[BUFSIZ];
343 snprintf(buf, sizeof(buf), "%g", nan(""));
Elliott Hughes4bd97ce2014-04-10 17:48:14 -0700344 EXPECT_STRCASEEQ("NaN", buf);
Elliott Hughes7823f322014-04-14 12:11:28 -0700345
346 snprintf(buf, sizeof(buf), "%g", HUGE_VAL);
Elliott Hughes4bd97ce2014-04-10 17:48:14 -0700347 EXPECT_STRCASEEQ("Inf", buf);
Elliott Hughes7823f322014-04-14 12:11:28 -0700348}
349
Elliott Hughes1d13c642013-09-23 16:02:39 -0700350TEST(stdio, snprintf_d_INT_MAX) {
351 char buf[BUFSIZ];
352 snprintf(buf, sizeof(buf), "%d", INT_MAX);
353 EXPECT_STREQ("2147483647", buf);
354}
355
356TEST(stdio, snprintf_d_INT_MIN) {
357 char buf[BUFSIZ];
358 snprintf(buf, sizeof(buf), "%d", INT_MIN);
359 EXPECT_STREQ("-2147483648", buf);
360}
361
362TEST(stdio, snprintf_ld_LONG_MAX) {
363 char buf[BUFSIZ];
364 snprintf(buf, sizeof(buf), "%ld", LONG_MAX);
Elliott Hughes925753a2013-10-18 13:17:18 -0700365#if __LP64__
366 EXPECT_STREQ("9223372036854775807", buf);
367#else
Elliott Hughes1d13c642013-09-23 16:02:39 -0700368 EXPECT_STREQ("2147483647", buf);
Elliott Hughes925753a2013-10-18 13:17:18 -0700369#endif
Elliott Hughes1d13c642013-09-23 16:02:39 -0700370}
371
372TEST(stdio, snprintf_ld_LONG_MIN) {
373 char buf[BUFSIZ];
374 snprintf(buf, sizeof(buf), "%ld", LONG_MIN);
Elliott Hughes925753a2013-10-18 13:17:18 -0700375#if __LP64__
376 EXPECT_STREQ("-9223372036854775808", buf);
377#else
Elliott Hughes1d13c642013-09-23 16:02:39 -0700378 EXPECT_STREQ("-2147483648", buf);
Elliott Hughes925753a2013-10-18 13:17:18 -0700379#endif
Elliott Hughes1d13c642013-09-23 16:02:39 -0700380}
381
382TEST(stdio, snprintf_lld_LLONG_MAX) {
383 char buf[BUFSIZ];
384 snprintf(buf, sizeof(buf), "%lld", LLONG_MAX);
385 EXPECT_STREQ("9223372036854775807", buf);
386}
387
388TEST(stdio, snprintf_lld_LLONG_MIN) {
389 char buf[BUFSIZ];
390 snprintf(buf, sizeof(buf), "%lld", LLONG_MIN);
391 EXPECT_STREQ("-9223372036854775808", buf);
392}
393
Elliott Hughes4bd97ce2014-04-10 17:48:14 -0700394TEST(stdio, snprintf_e) {
395 char buf[BUFSIZ];
396
397 snprintf(buf, sizeof(buf), "%e", 1.5);
398 EXPECT_STREQ("1.500000e+00", buf);
399
400 snprintf(buf, sizeof(buf), "%Le", 1.5l);
401 EXPECT_STREQ("1.500000e+00", buf);
402}
403
Elliott Hughese77f38f2014-05-14 12:39:12 -0700404TEST(stdio, snprintf_negative_zero_5084292) {
405 char buf[BUFSIZ];
406
407 snprintf(buf, sizeof(buf), "%f", -0.0);
408 EXPECT_STREQ("-0.000000", buf);
409}
410
Elliott Hughesc9244bd2014-05-14 13:31:35 -0700411TEST(stdio, fprintf_failures_7229520) {
412 FILE* fp;
413
414 // Unbuffered case where the fprintf(3) itself fails.
415 ASSERT_NE(nullptr, fp = tmpfile());
416 setbuf(fp, NULL);
417 ASSERT_EQ(4, fprintf(fp, "epic"));
418 ASSERT_EQ(0, close(fileno(fp)));
419 ASSERT_EQ(-1, fprintf(fp, "fail"));
420 ASSERT_EQ(-1, fclose(fp));
421
422 // Buffered case where we won't notice until the fclose(3).
423 // It's likely this is what was actually seen in http://b/7229520,
424 // and that expecting fprintf to fail is setting yourself up for
425 // disappointment. Remember to check fclose(3)'s return value, kids!
426 ASSERT_NE(nullptr, fp = tmpfile());
427 ASSERT_EQ(4, fprintf(fp, "epic"));
428 ASSERT_EQ(0, close(fileno(fp)));
429 ASSERT_EQ(4, fprintf(fp, "fail"));
430 ASSERT_EQ(-1, fclose(fp));
431}
432
Elliott Hughes6b3f49a2013-03-06 16:20:55 -0800433TEST(stdio, popen) {
434 FILE* fp = popen("cat /proc/version", "r");
435 ASSERT_TRUE(fp != NULL);
436
437 char buf[16];
438 char* s = fgets(buf, sizeof(buf), fp);
439 buf[13] = '\0';
440 ASSERT_STREQ("Linux version", s);
441
442 ASSERT_EQ(0, pclose(fp));
443}
Elliott Hughes6b05c8e2013-04-11 13:54:48 -0700444
445TEST(stdio, getc) {
446 FILE* fp = fopen("/proc/version", "r");
447 ASSERT_TRUE(fp != NULL);
448 ASSERT_EQ('L', getc(fp));
449 ASSERT_EQ('i', getc(fp));
450 ASSERT_EQ('n', getc(fp));
451 ASSERT_EQ('u', getc(fp));
452 ASSERT_EQ('x', getc(fp));
453 fclose(fp);
454}
455
456TEST(stdio, putc) {
457 FILE* fp = fopen("/proc/version", "r");
458 ASSERT_TRUE(fp != NULL);
459 ASSERT_EQ(EOF, putc('x', fp));
460 fclose(fp);
461}
Elliott Hughes603332f2014-03-12 17:10:41 -0700462
463TEST(stdio, sscanf) {
464 char s1[123];
465 int i1;
466 double d1;
467 char s2[123];
468 ASSERT_EQ(3, sscanf(" hello 123 1.23 ", "%s %i %lf %s", s1, &i1, &d1, s2));
469 ASSERT_STREQ("hello", s1);
470 ASSERT_EQ(123, i1);
Christopher Ferrisf171b342014-03-17 16:40:26 -0700471 ASSERT_DOUBLE_EQ(1.23, d1);
Elliott Hughes603332f2014-03-12 17:10:41 -0700472}
Elliott Hughes53b24382014-05-02 18:29:25 -0700473
474TEST(stdio, cantwrite_EBADF) {
475 // If we open a file read-only...
476 FILE* fp = fopen("/proc/version", "r");
477
478 // ...all attempts to write to that file should return failure.
479
480 // They should also set errno to EBADF. This isn't POSIX, but it's traditional.
481 // glibc gets the wide-character functions wrong.
482
483 errno = 0;
484 EXPECT_EQ(EOF, putc('x', fp));
485 EXPECT_EQ(EBADF, errno);
486
487 errno = 0;
488 EXPECT_EQ(EOF, fprintf(fp, "hello"));
489 EXPECT_EQ(EBADF, errno);
490
491 errno = 0;
492 EXPECT_EQ(EOF, fwprintf(fp, L"hello"));
Elliott Hughes063525c2014-05-13 11:19:57 -0700493#if defined(__BIONIC__)
Elliott Hughes53b24382014-05-02 18:29:25 -0700494 EXPECT_EQ(EBADF, errno);
495#endif
496
497 errno = 0;
498 EXPECT_EQ(EOF, putw(1234, fp));
499 EXPECT_EQ(EBADF, errno);
500
501 errno = 0;
502 EXPECT_EQ(0U, fwrite("hello", 1, 2, fp));
503 EXPECT_EQ(EBADF, errno);
504
505 errno = 0;
506 EXPECT_EQ(EOF, fputs("hello", fp));
507 EXPECT_EQ(EBADF, errno);
508
509 errno = 0;
510 EXPECT_EQ(WEOF, fputwc(L'x', fp));
Elliott Hughes063525c2014-05-13 11:19:57 -0700511#if defined(__BIONIC__)
Elliott Hughes53b24382014-05-02 18:29:25 -0700512 EXPECT_EQ(EBADF, errno);
513#endif
514}
Calin Juravle03e4ebe2014-05-08 14:42:06 +0100515
516// Tests that we can only have a consistent and correct fpos_t when using
517// f*pos functions (i.e. fpos doesn't get inside a multi byte character).
518TEST(stdio, consistent_fpos_t) {
519 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
520 uselocale(LC_GLOBAL_LOCALE);
521
522 FILE* fp = tmpfile();
523 ASSERT_TRUE(fp != NULL);
524
525 wchar_t mb_one_bytes = L'h';
526 wchar_t mb_two_bytes = 0x00a2;
527 wchar_t mb_three_bytes = 0x20ac;
528 wchar_t mb_four_bytes = 0x24b62;
529
530 // Write to file.
531 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fputwc(mb_one_bytes, fp)));
532 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp)));
533 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp)));
534 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp)));
535
536 rewind(fp);
537
538 // Record each character position.
539 fpos_t pos1;
540 fpos_t pos2;
541 fpos_t pos3;
542 fpos_t pos4;
543 fpos_t pos5;
544 EXPECT_EQ(0, fgetpos(fp, &pos1));
545 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp)));
546 EXPECT_EQ(0, fgetpos(fp, &pos2));
547 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp)));
548 EXPECT_EQ(0, fgetpos(fp, &pos3));
549 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp)));
550 EXPECT_EQ(0, fgetpos(fp, &pos4));
551 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp)));
552 EXPECT_EQ(0, fgetpos(fp, &pos5));
553
Elliott Hughes063525c2014-05-13 11:19:57 -0700554#if defined(__BIONIC__)
Calin Juravle03e4ebe2014-05-08 14:42:06 +0100555 // Bionic's fpos_t is just an alias for off_t. This is inherited from OpenBSD
556 // upstream. Glibc differs by storing the mbstate_t inside its fpos_t. In
557 // Bionic (and upstream OpenBSD) the mbstate_t is stored inside the FILE
558 // structure.
559 ASSERT_EQ(0, static_cast<off_t>(pos1));
560 ASSERT_EQ(1, static_cast<off_t>(pos2));
561 ASSERT_EQ(3, static_cast<off_t>(pos3));
562 ASSERT_EQ(6, static_cast<off_t>(pos4));
563 ASSERT_EQ(10, static_cast<off_t>(pos5));
564#endif
565
566 // Exercise back and forth movements of the position.
567 ASSERT_EQ(0, fsetpos(fp, &pos2));
568 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp)));
569 ASSERT_EQ(0, fsetpos(fp, &pos1));
570 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp)));
571 ASSERT_EQ(0, fsetpos(fp, &pos4));
572 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp)));
573 ASSERT_EQ(0, fsetpos(fp, &pos3));
574 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp)));
575 ASSERT_EQ(0, fsetpos(fp, &pos5));
576 ASSERT_EQ(WEOF, fgetwc(fp));
577
578 fclose(fp);
579}
580
581// Exercise the interaction between fpos and seek.
582TEST(stdio, fpos_t_and_seek) {
583 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
584 uselocale(LC_GLOBAL_LOCALE);
585
586 // For glibc we need to close and re-open the file in order for fseek to work
587 // after using setlocale(LC_CTYPE, "C.UTF-8") and fputwc.
588 // TODO: find out if this is expected or a bug in glibc.
589 TemporaryFile tf;
590 FILE* fp = fdopen(tf.fd, "w+");
591 ASSERT_TRUE(fp != NULL);
592
593 wchar_t mb_two_bytes = 0x00a2;
594 wchar_t mb_three_bytes = 0x20ac;
595 wchar_t mb_four_bytes = 0x24b62;
596
597 // Write to file.
598 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp)));
599 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp)));
600 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp)));
601
602 fflush(fp);
603 fclose(fp);
604
605 fp = fopen(tf.filename, "r");
606 ASSERT_TRUE(fp != NULL);
607
608 // Store a valid position.
609 fpos_t mb_two_bytes_pos;
610 ASSERT_EQ(0, fgetpos(fp, &mb_two_bytes_pos));
611
612 // Move inside mb_four_bytes with fseek.
613 long offset_inside_mb = 6;
614 ASSERT_EQ(0, fseek(fp, offset_inside_mb, SEEK_SET));
615
616 // Store the "inside multi byte" position.
617 fpos_t pos_inside_mb;
618 ASSERT_EQ(0, fgetpos(fp, &pos_inside_mb));
Elliott Hughes063525c2014-05-13 11:19:57 -0700619#if defined(__BIONIC__)
620 ASSERT_EQ(offset_inside_mb, static_cast<off_t>(pos_inside_mb));
621#endif
Calin Juravle03e4ebe2014-05-08 14:42:06 +0100622
623 // Reading from within a byte should produce an error.
624 ASSERT_EQ(WEOF, fgetwc(fp));
625 ASSERT_EQ(EILSEQ, errno);
626
627 // Reverting to a valid position should work.
628 ASSERT_EQ(0, fsetpos(fp, &mb_two_bytes_pos));
629 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp)));
630
631 // Moving withing a multi byte with fsetpos should work but reading should
632 // produce an error.
633 ASSERT_EQ(0, fsetpos(fp, &pos_inside_mb));
634 ASSERT_EQ(WEOF, fgetwc(fp));
635 ASSERT_EQ(EILSEQ, errno);
636
637 fclose(fp);
638}