• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TEST(stdio,tmpfile_fileno_fprintf_rewind_fgets)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 
TEST(stdio,getdelim)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 
TEST(stdio,getdelim_invalid)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 
TEST(stdio,getline)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 
TEST(stdio,getline_invalid)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 
TEST(stdio,printf_ssize_t)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 
TEST(stdio,popen)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 
TEST(stdio,getc)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 
TEST(stdio,putc)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