stdio_test.cpp revision 603332fc4c2d073f0e197f9ce4517710e9b3a6d0
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 <limits.h> 21#include <stdio.h> 22#include <sys/types.h> 23#include <sys/stat.h> 24#include <unistd.h> 25 26TEST(stdio, tmpfile_fileno_fprintf_rewind_fgets) { 27 FILE* fp = tmpfile(); 28 ASSERT_TRUE(fp != NULL); 29 30 int fd = fileno(fp); 31 ASSERT_NE(fd, -1); 32 33 struct stat sb; 34 int rc = fstat(fd, &sb); 35 ASSERT_NE(rc, -1); 36 ASSERT_EQ(sb.st_mode & 0777, 0600U); 37 38 rc = fprintf(fp, "hello\n"); 39 ASSERT_EQ(rc, 6); 40 41 rewind(fp); 42 43 char buf[16]; 44 char* s = fgets(buf, sizeof(buf), fp); 45 ASSERT_TRUE(s != NULL); 46 ASSERT_STREQ("hello\n", s); 47 48 fclose(fp); 49} 50 51TEST(stdio, getdelim) { 52 FILE* fp = tmpfile(); 53 ASSERT_TRUE(fp != NULL); 54 55 const char* line_written = "This is a test"; 56 int rc = fprintf(fp, "%s", line_written); 57 ASSERT_EQ(rc, static_cast<int>(strlen(line_written))); 58 59 rewind(fp); 60 61 char* word_read = NULL; 62 size_t allocated_length = 0; 63 64 const char* expected[] = { "This ", " ", "is ", "a ", "test" }; 65 for (size_t i = 0; i < 5; ++i) { 66 ASSERT_FALSE(feof(fp)); 67 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), static_cast<int>(strlen(expected[i]))); 68 ASSERT_GE(allocated_length, strlen(expected[i])); 69 ASSERT_STREQ(word_read, expected[i]); 70 } 71 // The last read should have set the end-of-file indicator for the stream. 72 ASSERT_TRUE(feof(fp)); 73 clearerr(fp); 74 75 // getdelim returns -1 but doesn't set errno if we're already at EOF. 76 // It should set the end-of-file indicator for the stream, though. 77 errno = 0; 78 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), -1); 79 ASSERT_EQ(0, errno); 80 ASSERT_TRUE(feof(fp)); 81 82 free(word_read); 83 fclose(fp); 84} 85 86TEST(stdio, getdelim_invalid) { 87 FILE* fp = tmpfile(); 88 ASSERT_TRUE(fp != NULL); 89 90 char* buffer = NULL; 91 size_t buffer_length = 0; 92 93 // The first argument can't be NULL. 94 errno = 0; 95 ASSERT_EQ(getdelim(NULL, &buffer_length, ' ', fp), -1); 96 ASSERT_EQ(EINVAL, errno); 97 98 // The second argument can't be NULL. 99 errno = 0; 100 ASSERT_EQ(getdelim(&buffer, NULL, ' ', fp), -1); 101 ASSERT_EQ(EINVAL, errno); 102 103 // The stream can't be closed. 104 fclose(fp); 105 errno = 0; 106 ASSERT_EQ(getdelim(&buffer, &buffer_length, ' ', fp), -1); 107 // glibc sometimes doesn't set errno in this particular case. 108#if defined(__BIONIC__) 109 ASSERT_EQ(EBADF, errno); 110#endif // __BIONIC__ 111} 112 113TEST(stdio, getline) { 114 FILE* fp = tmpfile(); 115 ASSERT_TRUE(fp != NULL); 116 117 const char* line_written = "This is a test for getline\n"; 118 const size_t line_count = 5; 119 120 for (size_t i = 0; i < line_count; ++i) { 121 int rc = fprintf(fp, "%s", line_written); 122 ASSERT_EQ(rc, static_cast<int>(strlen(line_written))); 123 } 124 125 rewind(fp); 126 127 char* line_read = NULL; 128 size_t allocated_length = 0; 129 130 size_t read_line_count = 0; 131 ssize_t read_char_count; 132 while ((read_char_count = getline(&line_read, &allocated_length, fp)) != -1) { 133 ASSERT_EQ(read_char_count, static_cast<int>(strlen(line_written))); 134 ASSERT_GE(allocated_length, strlen(line_written)); 135 ASSERT_STREQ(line_read, line_written); 136 ++read_line_count; 137 } 138 ASSERT_EQ(read_line_count, line_count); 139 140 // The last read should have set the end-of-file indicator for the stream. 141 ASSERT_TRUE(feof(fp)); 142 clearerr(fp); 143 144 // getline returns -1 but doesn't set errno if we're already at EOF. 145 // It should set the end-of-file indicator for the stream, though. 146 errno = 0; 147 ASSERT_EQ(getline(&line_read, &allocated_length, fp), -1); 148 ASSERT_EQ(0, errno); 149 ASSERT_TRUE(feof(fp)); 150 151 free(line_read); 152 fclose(fp); 153} 154 155TEST(stdio, getline_invalid) { 156 FILE* fp = tmpfile(); 157 ASSERT_TRUE(fp != NULL); 158 159 char* buffer = NULL; 160 size_t buffer_length = 0; 161 162 // The first argument can't be NULL. 163 errno = 0; 164 ASSERT_EQ(getline(NULL, &buffer_length, fp), -1); 165 ASSERT_EQ(EINVAL, errno); 166 167 // The second argument can't be NULL. 168 errno = 0; 169 ASSERT_EQ(getline(&buffer, NULL, fp), -1); 170 ASSERT_EQ(EINVAL, errno); 171 172 // The stream can't be closed. 173 fclose(fp); 174 errno = 0; 175 ASSERT_EQ(getline(&buffer, &buffer_length, fp), -1); 176 // glibc sometimes doesn't set errno in this particular case. 177#if defined(__BIONIC__) 178 ASSERT_EQ(EBADF, errno); 179#endif // __BIONIC__ 180} 181 182TEST(stdio, printf_ssize_t) { 183 // http://b/8253769 184 ASSERT_EQ(sizeof(ssize_t), sizeof(long int)); 185 ASSERT_EQ(sizeof(ssize_t), sizeof(size_t)); 186 // For our 32-bit ABI, we had a ssize_t definition that confuses GCC into saying: 187 // error: format '%zd' expects argument of type 'signed size_t', 188 // but argument 4 has type 'ssize_t {aka long int}' [-Werror=format] 189 ssize_t v = 1; 190 char buf[32]; 191 snprintf(buf, sizeof(buf), "%zd", v); 192} 193 194TEST(stdio, snprintf_n_format_specifier_not_implemented) { 195#if defined(__BIONIC__) 196 char buf[32]; 197 int i = 0; 198 // We deliberately don't implement %n, so it's treated like 199 // any other unrecognized format specifier. 200 EXPECT_EQ(5, snprintf(buf, sizeof(buf), "a %n b", &i)); 201 EXPECT_EQ(0, i); 202 EXPECT_STREQ("a n b", buf); 203#else // __BIONIC__ 204 GTEST_LOG_(INFO) << "This test does nothing.\n"; 205#endif // __BIONIC__ 206} 207 208TEST(stdio, snprintf_smoke) { 209 char buf[BUFSIZ]; 210 211 snprintf(buf, sizeof(buf), "a"); 212 EXPECT_STREQ("a", buf); 213 214 snprintf(buf, sizeof(buf), "%%"); 215 EXPECT_STREQ("%", buf); 216 217 snprintf(buf, sizeof(buf), "01234"); 218 EXPECT_STREQ("01234", buf); 219 220 snprintf(buf, sizeof(buf), "a%sb", "01234"); 221 EXPECT_STREQ("a01234b", buf); 222 223 char* s = NULL; 224 snprintf(buf, sizeof(buf), "a%sb", s); 225 EXPECT_STREQ("a(null)b", buf); 226 227 snprintf(buf, sizeof(buf), "aa%scc", "bb"); 228 EXPECT_STREQ("aabbcc", buf); 229 230 snprintf(buf, sizeof(buf), "a%cc", 'b'); 231 EXPECT_STREQ("abc", buf); 232 233 snprintf(buf, sizeof(buf), "a%db", 1234); 234 EXPECT_STREQ("a1234b", buf); 235 236 snprintf(buf, sizeof(buf), "a%db", -8123); 237 EXPECT_STREQ("a-8123b", buf); 238 239 snprintf(buf, sizeof(buf), "a%hdb", static_cast<short>(0x7fff0010)); 240 EXPECT_STREQ("a16b", buf); 241 242 snprintf(buf, sizeof(buf), "a%hhdb", static_cast<char>(0x7fffff10)); 243 EXPECT_STREQ("a16b", buf); 244 245 snprintf(buf, sizeof(buf), "a%lldb", 0x1000000000LL); 246 EXPECT_STREQ("a68719476736b", buf); 247 248 snprintf(buf, sizeof(buf), "a%ldb", 70000L); 249 EXPECT_STREQ("a70000b", buf); 250 251 snprintf(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234)); 252 EXPECT_STREQ("a0xb0001234b", buf); 253 254 snprintf(buf, sizeof(buf), "a%xz", 0x12ab); 255 EXPECT_STREQ("a12abz", buf); 256 257 snprintf(buf, sizeof(buf), "a%Xz", 0x12ab); 258 EXPECT_STREQ("a12ABz", buf); 259 260 snprintf(buf, sizeof(buf), "a%08xz", 0x123456); 261 EXPECT_STREQ("a00123456z", buf); 262 263 snprintf(buf, sizeof(buf), "a%5dz", 1234); 264 EXPECT_STREQ("a 1234z", buf); 265 266 snprintf(buf, sizeof(buf), "a%05dz", 1234); 267 EXPECT_STREQ("a01234z", buf); 268 269 snprintf(buf, sizeof(buf), "a%8dz", 1234); 270 EXPECT_STREQ("a 1234z", buf); 271 272 snprintf(buf, sizeof(buf), "a%-8dz", 1234); 273 EXPECT_STREQ("a1234 z", buf); 274 275 snprintf(buf, sizeof(buf), "A%-11sZ", "abcdef"); 276 EXPECT_STREQ("Aabcdef Z", buf); 277 278 snprintf(buf, sizeof(buf), "A%s:%dZ", "hello", 1234); 279 EXPECT_STREQ("Ahello:1234Z", buf); 280 281 snprintf(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5); 282 EXPECT_STREQ("a005:5:05z", buf); 283 284 void* p = NULL; 285 snprintf(buf, sizeof(buf), "a%d,%pz", 5, p); 286#if defined(__BIONIC__) 287 EXPECT_STREQ("a5,0x0z", buf); 288#else // __BIONIC__ 289 EXPECT_STREQ("a5,(nil)z", buf); 290#endif // __BIONIC__ 291 292 snprintf(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8); 293 EXPECT_STREQ("a68719476736,6,7,8z", buf); 294 295 snprintf(buf, sizeof(buf), "a_%f_b", 1.23f); 296 EXPECT_STREQ("a_1.230000_b", buf); 297 298 snprintf(buf, sizeof(buf), "a_%g_b", 3.14); 299 EXPECT_STREQ("a_3.14_b", buf); 300} 301 302TEST(stdio, snprintf_d_INT_MAX) { 303 char buf[BUFSIZ]; 304 snprintf(buf, sizeof(buf), "%d", INT_MAX); 305 EXPECT_STREQ("2147483647", buf); 306} 307 308TEST(stdio, snprintf_d_INT_MIN) { 309 char buf[BUFSIZ]; 310 snprintf(buf, sizeof(buf), "%d", INT_MIN); 311 EXPECT_STREQ("-2147483648", buf); 312} 313 314TEST(stdio, snprintf_ld_LONG_MAX) { 315 char buf[BUFSIZ]; 316 snprintf(buf, sizeof(buf), "%ld", LONG_MAX); 317#if __LP64__ 318 EXPECT_STREQ("9223372036854775807", buf); 319#else 320 EXPECT_STREQ("2147483647", buf); 321#endif 322} 323 324TEST(stdio, snprintf_ld_LONG_MIN) { 325 char buf[BUFSIZ]; 326 snprintf(buf, sizeof(buf), "%ld", LONG_MIN); 327#if __LP64__ 328 EXPECT_STREQ("-9223372036854775808", buf); 329#else 330 EXPECT_STREQ("-2147483648", buf); 331#endif 332} 333 334TEST(stdio, snprintf_lld_LLONG_MAX) { 335 char buf[BUFSIZ]; 336 snprintf(buf, sizeof(buf), "%lld", LLONG_MAX); 337 EXPECT_STREQ("9223372036854775807", buf); 338} 339 340TEST(stdio, snprintf_lld_LLONG_MIN) { 341 char buf[BUFSIZ]; 342 snprintf(buf, sizeof(buf), "%lld", LLONG_MIN); 343 EXPECT_STREQ("-9223372036854775808", buf); 344} 345 346TEST(stdio, popen) { 347 FILE* fp = popen("cat /proc/version", "r"); 348 ASSERT_TRUE(fp != NULL); 349 350 char buf[16]; 351 char* s = fgets(buf, sizeof(buf), fp); 352 buf[13] = '\0'; 353 ASSERT_STREQ("Linux version", s); 354 355 ASSERT_EQ(0, pclose(fp)); 356} 357 358TEST(stdio, getc) { 359 FILE* fp = fopen("/proc/version", "r"); 360 ASSERT_TRUE(fp != NULL); 361 ASSERT_EQ('L', getc(fp)); 362 ASSERT_EQ('i', getc(fp)); 363 ASSERT_EQ('n', getc(fp)); 364 ASSERT_EQ('u', getc(fp)); 365 ASSERT_EQ('x', getc(fp)); 366 fclose(fp); 367} 368 369TEST(stdio, putc) { 370 FILE* fp = fopen("/proc/version", "r"); 371 ASSERT_TRUE(fp != NULL); 372 ASSERT_EQ(EOF, putc('x', fp)); 373 fclose(fp); 374} 375 376TEST(stdio, sscanf) { 377 char s1[123]; 378 int i1; 379 double d1; 380 char s2[123]; 381 ASSERT_EQ(3, sscanf(" hello 123 1.23 ", "%s %i %lf %s", s1, &i1, &d1, s2)); 382 ASSERT_STREQ("hello", s1); 383 ASSERT_EQ(123, i1); 384 ASSERT_EQ(1.23, d1); 385} 386