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 <stdio.h> 21 #include <sys/types.h> 22 #include <sys/stat.h> 23 #include <unistd.h> 24 25 TEST(stdio, tmpfile_fileno_fprintf_rewind_fgets) { 26 FILE* fp = tmpfile(); 27 ASSERT_TRUE(fp != NULL); 28 29 int fd = fileno(fp); 30 ASSERT_NE(fd, -1); 31 32 struct stat sb; 33 int rc = fstat(fd, &sb); 34 ASSERT_NE(rc, -1); 35 ASSERT_EQ(sb.st_mode & 0777, 0600U); 36 37 rc = fprintf(fp, "hello\n"); 38 ASSERT_EQ(rc, 6); 39 40 rewind(fp); 41 42 char buf[16]; 43 char* s = fgets(buf, sizeof(buf), fp); 44 ASSERT_TRUE(s != NULL); 45 ASSERT_STREQ("hello\n", s); 46 47 fclose(fp); 48 } 49 50 TEST(stdio, getdelim) { 51 FILE* fp = tmpfile(); 52 ASSERT_TRUE(fp != NULL); 53 54 const char* line_written = "This is a test"; 55 int rc = fprintf(fp, "%s", line_written); 56 ASSERT_EQ(rc, static_cast<int>(strlen(line_written))); 57 58 rewind(fp); 59 60 char* word_read = NULL; 61 size_t allocated_length = 0; 62 63 const char* expected[] = { "This ", " ", "is ", "a ", "test" }; 64 for (size_t i = 0; i < 5; ++i) { 65 ASSERT_FALSE(feof(fp)); 66 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), static_cast<int>(strlen(expected[i]))); 67 ASSERT_GE(allocated_length, strlen(expected[i])); 68 ASSERT_STREQ(word_read, expected[i]); 69 } 70 // The last read should have set the end-of-file indicator for the stream. 71 ASSERT_TRUE(feof(fp)); 72 clearerr(fp); 73 74 // getdelim returns -1 but doesn't set errno if we're already at EOF. 75 // It should set the end-of-file indicator for the stream, though. 76 errno = 0; 77 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), -1); 78 ASSERT_EQ(0, errno); 79 ASSERT_TRUE(feof(fp)); 80 81 free(word_read); 82 fclose(fp); 83 } 84 85 TEST(stdio, getdelim_invalid) { 86 FILE* fp = tmpfile(); 87 88 char* buffer = NULL; 89 size_t buffer_length = 0; 90 91 // The first argument can't be NULL. 92 errno = 0; 93 ASSERT_EQ(getdelim(NULL, &buffer_length, ' ', fp), -1); 94 ASSERT_EQ(EINVAL, errno); 95 96 // The second argument can't be NULL. 97 errno = 0; 98 ASSERT_EQ(getdelim(&buffer, NULL, ' ', fp), -1); 99 ASSERT_EQ(EINVAL, errno); 100 101 // The stream can't be closed. 102 fclose(fp); 103 errno = 0; 104 ASSERT_EQ(getdelim(&buffer, &buffer_length, ' ', fp), -1); 105 ASSERT_EQ(EBADF, errno); 106 } 107 108 TEST(stdio, getline) { 109 FILE* fp = tmpfile(); 110 ASSERT_TRUE(fp != NULL); 111 112 const char* line_written = "This is a test for getline\n"; 113 const size_t line_count = 5; 114 115 for (size_t i = 0; i < line_count; ++i) { 116 int rc = fprintf(fp, "%s", line_written); 117 ASSERT_EQ(rc, static_cast<int>(strlen(line_written))); 118 } 119 120 rewind(fp); 121 122 char* line_read = NULL; 123 size_t allocated_length = 0; 124 125 size_t read_line_count = 0; 126 ssize_t read_char_count; 127 while ((read_char_count = getline(&line_read, &allocated_length, fp)) != -1) { 128 ASSERT_EQ(read_char_count, static_cast<int>(strlen(line_written))); 129 ASSERT_GE(allocated_length, strlen(line_written)); 130 ASSERT_STREQ(line_read, line_written); 131 ++read_line_count; 132 } 133 ASSERT_EQ(read_line_count, line_count); 134 135 // The last read should have set the end-of-file indicator for the stream. 136 ASSERT_TRUE(feof(fp)); 137 clearerr(fp); 138 139 // getline returns -1 but doesn't set errno if we're already at EOF. 140 // It should set the end-of-file indicator for the stream, though. 141 errno = 0; 142 ASSERT_EQ(getline(&line_read, &allocated_length, fp), -1); 143 ASSERT_EQ(0, errno); 144 ASSERT_TRUE(feof(fp)); 145 146 free(line_read); 147 fclose(fp); 148 } 149 150 TEST(stdio, getline_invalid) { 151 FILE* fp = tmpfile(); 152 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(getline(NULL, &buffer_length, fp), -1); 159 ASSERT_EQ(EINVAL, errno); 160 161 // The second argument can't be NULL. 162 errno = 0; 163 ASSERT_EQ(getline(&buffer, NULL, fp), -1); 164 ASSERT_EQ(EINVAL, errno); 165 166 // The stream can't be closed. 167 fclose(fp); 168 errno = 0; 169 ASSERT_EQ(getline(&buffer, &buffer_length, fp), -1); 170 ASSERT_EQ(EBADF, errno); 171 } 172 173 TEST(stdio, printf_ssize_t) { 174 // http://b/8253769 175 ASSERT_EQ(sizeof(ssize_t), sizeof(long int)); 176 ASSERT_EQ(sizeof(ssize_t), sizeof(size_t)); 177 // For our 32-bit ABI, we had a ssize_t definition that confuses GCC into saying: 178 // error: format '%zd' expects argument of type 'signed size_t', 179 // but argument 4 has type 'ssize_t {aka long int}' [-Werror=format] 180 ssize_t v = 1; 181 char buf[32]; 182 snprintf(buf, sizeof(buf), "%zd", v); 183 } 184 185 TEST(stdio, popen) { 186 FILE* fp = popen("cat /proc/version", "r"); 187 ASSERT_TRUE(fp != NULL); 188 189 char buf[16]; 190 char* s = fgets(buf, sizeof(buf), fp); 191 buf[13] = '\0'; 192 ASSERT_STREQ("Linux version", s); 193 194 ASSERT_EQ(0, pclose(fp)); 195 } 196 197 TEST(stdio, getc) { 198 FILE* fp = fopen("/proc/version", "r"); 199 ASSERT_TRUE(fp != NULL); 200 ASSERT_EQ('L', getc(fp)); 201 ASSERT_EQ('i', getc(fp)); 202 ASSERT_EQ('n', getc(fp)); 203 ASSERT_EQ('u', getc(fp)); 204 ASSERT_EQ('x', getc(fp)); 205 fclose(fp); 206 } 207 208 TEST(stdio, putc) { 209 FILE* fp = fopen("/proc/version", "r"); 210 ASSERT_TRUE(fp != NULL); 211 ASSERT_EQ(EOF, putc('x', fp)); 212 fclose(fp); 213 } 214