1 /*
2 * Copyright (c) 2020 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include <fcntl.h>
9 #include <zephyr/posix/unistd.h>
10 #include "test_fs.h"
11
12 #define THE_FILE FATFS_MNTP"/the_file.txt"
13
test_file_open_flags(void)14 static int test_file_open_flags(void)
15 {
16 int fd = 0;
17 int data = 0;
18 int ret;
19
20 /* 1 Check opening non-existent without O_CREAT */
21 TC_PRINT("Open of non-existent file, flags = 0\n");
22 fd = open(THE_FILE, 0);
23 if (fd >= 0 || errno != ENOENT) {
24 TC_PRINT("Expected fail; fd = %d, errno = %d\n", fd, errno);
25 close(fd);
26 return TC_FAIL;
27 }
28
29 TC_PRINT("Open on non-existent file, flags = O_RDONLY\n");
30 fd = open(THE_FILE, O_RDONLY);
31 if (fd >= 0 || errno != ENOENT) {
32 TC_PRINT("Expected fail; fd = %d, errno = %d\n", fd, errno);
33 close(fd);
34 return TC_FAIL;
35 }
36 TC_PRINT("Open on non-existent file, flags = O_WRONLY\n");
37 fd = open(THE_FILE, O_WRONLY);
38 if (fd >= 0 || errno != ENOENT) {
39 TC_PRINT("Expected fail; fd = %d, errno = %d\n", fd, errno);
40 close(fd);
41 return TC_FAIL;
42 }
43
44 TC_PRINT("Open on non-existent file, flags = O_RDWR\n");
45 fd = open(THE_FILE, O_RDWR);
46 if (fd >= 0 || errno != ENOENT) {
47 TC_PRINT("Expected fail; fd = %d, errno = %d\n", fd, errno);
48 close(fd);
49 return TC_FAIL;
50 }
51 /* end 1 */
52
53 /* 2 Create file for read only, attempt to read, attempt to write */
54 TC_PRINT("Open on non-existent file, flags = O_CREAT | O_WRONLY\n");
55 fd = open(THE_FILE, O_CREAT | O_WRONLY);
56 if (fd < 0) {
57 TC_PRINT("Expected success; fd = %d, errno = %d\n", fd, errno);
58 return TC_FAIL;
59 }
60
61 TC_PRINT("Attempt read file opened with flags = O_CREAT | O_WRONLY\n");
62 ret = read(fd, &data, sizeof(data));
63 if (ret > 0 || errno != EACCES) {
64 TC_PRINT("Expected fail, ret = %d, errno = %d\n", ret, errno);
65 close(fd);
66 return TC_FAIL;
67 }
68
69 TC_PRINT("Attempt write file opened with flags = O_CREAT | O_WRONLY\n");
70 ret = write(fd, &data, sizeof(data));
71 if (ret <= 0 || errno != EACCES) {
72 TC_PRINT("Expected success, ret = %d, errno = %d\n", ret,
73 errno);
74 close(fd);
75 return TC_FAIL;
76 }
77
78 close(fd);
79 /* end 2 */
80
81
82 /* 3 Attempt read/write operation on file opened with flags = 0 */
83 TC_PRINT("Attempt open existing with flags = 0\n");
84 fd = open(THE_FILE, 0);
85 if (fd < 0) {
86 TC_PRINT("Expected success, fd = %d, errno = %d\n", fd, errno);
87 return TC_FAIL;
88 }
89
90 TC_PRINT("Attempt read file opened with flags = 0\n");
91 ret = read(fd, &data, sizeof(data));
92 if (ret < 0) {
93 TC_PRINT("Expected success, ret = %d, errno = %d\n", ret,
94 errno);
95 close(fd);
96 return TC_FAIL;
97 }
98
99 TC_PRINT("Attempt write file opened with flags = 0\n");
100 ret = write(fd, &data, sizeof(data));
101 if (ret >= 0 || errno != EACCES) {
102 TC_PRINT("Expected fail, ret = %d, errno = %d\n", ret, errno);
103 close(fd);
104 return TC_FAIL;
105 }
106
107 close(fd);
108 /* end 3 */
109
110 /* 4 Attempt read/write on file opened with flags O_RDONLY */
111 /* File does have content after previous tests. */
112 TC_PRINT("Attempt open existing with flags = O_RDONLY\n");
113 fd = open(THE_FILE, O_RDONLY);
114 if (fd < 0) {
115 TC_PRINT("Expected success, fd = %d, errno = %d\n", fd, errno);
116 return TC_FAIL;
117 }
118
119 TC_PRINT("Attempt read file opened with flags = O_RDONLY\n");
120 ret = read(fd, &data, sizeof(data));
121 if (ret < 0) {
122 TC_PRINT("Expected success, ret = %d, errno = %d\n", ret,
123 errno);
124 close(fd);
125 return TC_FAIL;
126 }
127
128 TC_PRINT("Attempt write file opened with flags = O_RDONLY\n");
129 ret = write(fd, &data, sizeof(data));
130 if (ret >= 0 || errno != EACCES) {
131 TC_PRINT("Expected fail, ret = %d, errno = %d\n", ret, errno);
132 close(fd);
133 return TC_FAIL;
134 }
135
136 close(fd);
137 /* end 4 */
138
139 /* 5 Attempt read/write on file opened with flags O_WRONLY */
140 /* File does have content after previous tests. */
141 TC_PRINT("Attempt open existing with flags = O_WRONLY\n");
142 fd = open(THE_FILE, O_WRONLY);
143 if (fd < 0) {
144 TC_PRINT("Expected success, fd = %d, errno = %d\n", fd, errno);
145 return TC_FAIL;
146 }
147
148 TC_PRINT("Attempt read file opened with flags = O_WRONLY\n");
149 ret = read(fd, &data, sizeof(data));
150 if (ret >= 0 || errno != EACCES) {
151 TC_PRINT("Expected fail, ret = %d, errno = %d\n", ret, errno);
152 close(fd);
153 return TC_FAIL;
154 }
155
156 TC_PRINT("Attempt write file opened with flags = O_WRONLY\n");
157 ret = write(fd, &data, sizeof(data));
158 if (ret < 0) {
159 TC_PRINT("Expected success, ret = %d, errno = %d\n", ret,
160 errno);
161 close(fd);
162 return TC_FAIL;
163 }
164
165 close(fd);
166 /* end 5 */
167
168 /* 6 Attempt read/write on file opened with flags O_APPEND | O_WRONLY */
169 TC_PRINT("Attempt open existing with flags = O_APPEND | O_WRONLY\n");
170 fd = open(THE_FILE, O_APPEND | O_WRONLY);
171 if (fd < 0) {
172 TC_PRINT("Expected success, fd = %d, errno = %d\n", fd, errno);
173 return TC_FAIL;
174 }
175
176 TC_PRINT("Attempt read file opened with flags = O_APPEND | O_WRONLY\n");
177 ret = read(fd, &data, sizeof(data));
178 if (ret >= 0 || errno != EACCES) {
179 TC_PRINT("Expected fail, ret = %d, errno = %d\n", ret, errno);
180 close(fd);
181 return TC_FAIL;
182 }
183
184 TC_PRINT("Attempt write to opened with flags = O_APPEND | O_WRONLY\n");
185 ret = write(fd, &data, sizeof(data));
186 if (ret < 0) {
187 TC_PRINT("Expected success, ret = %d, errno = %d\n", ret,
188 errno);
189 close(fd);
190 return TC_FAIL;
191 }
192
193 close(fd);
194 /* end 6 */
195
196 /* 7 Attempt read/write on file opened with flags O_APPEND | O_RDWR */
197 TC_PRINT("Attempt open existing with flags = O_APPEND | O_RDWR\n");
198 fd = open(THE_FILE, O_APPEND | O_RDWR);
199 if (fd < 0) {
200 TC_PRINT("Expected success, fd = %d, errno = %d\n", fd, errno);
201 return TC_FAIL;
202 }
203
204
205 TC_PRINT("Attempt read file opened with flags = O_APPEND | O_RDWR\n");
206 lseek(fd, 0, SEEK_SET);
207 ret = read(fd, &data, sizeof(data));
208 if (ret < 0) {
209 TC_PRINT("Expected success, ret = %d, errno = %d\n", ret,
210 errno);
211 close(fd);
212 return TC_FAIL;
213 }
214
215 TC_PRINT("Attempt write file opened with flags = O_APPEND | O_RDWR\n");
216 ret = write(fd, &data, sizeof(data));
217 if (ret < 0) {
218 TC_PRINT("Expected success, ret = %d, errno = %d\n", ret,
219 errno);
220 close(fd);
221 return TC_FAIL;
222 }
223
224 close(fd);
225 /* end 7 */
226
227 /* 8 Check if appended file is always written at the end */
228 TC_PRINT("Attempt write to file opened with O_APPEND | O_RDWR\n");
229 /* Clean start */
230 unlink(THE_FILE);
231 fd = open(THE_FILE, O_CREAT | O_WRONLY);
232 if (fd < 0) {
233 TC_PRINT("Expected success, fd = %d, errno = %d\n", fd, errno);
234 return TC_FAIL;
235 }
236
237 ret = write(fd, &data, sizeof(data));
238 if (ret < 0) {
239 TC_PRINT("Expected success, ret = %d, errno = %d\n", ret,
240 errno);
241 close(fd);
242 return TC_FAIL;
243 }
244
245 close(fd);
246
247 fd = open(THE_FILE, O_APPEND | O_RDWR);
248 if (fd < 0) {
249 TC_PRINT("Expected success, fd = %d, errno = %d\n", fd, errno);
250 return TC_FAIL;
251 }
252
253 lseek(fd, 0, SEEK_SET);
254 ret = write(fd, &data, sizeof(data));
255 if (ret < 0) {
256 TC_PRINT("Expected success, ret = %d, errno = %d\n", ret,
257 errno);
258 close(fd);
259 return TC_FAIL;
260 }
261
262 ret = lseek(fd, 0, SEEK_END);
263
264 if (ret != (sizeof(data) * 2)) {
265 TC_PRINT("Expected file size %zu, ret = %d, errno = %d\n",
266 sizeof(data) * 2, ret, errno);
267 close(fd);
268 return TC_FAIL;
269 }
270
271 close(fd);
272 /* end 8 */
273
274 return TC_PASS;
275 }
276
277 /**
278 * @brief Test for POSIX open flags
279 *
280 * @details Test attempts to open file with different combinations of open
281 * flags and checks if operations on files are permitted according to flags.
282 */
ZTEST(posix_fs_test,test_fs_open_flags)283 ZTEST(posix_fs_test, test_fs_open_flags)
284 {
285 zassert_true(test_file_open_flags() == TC_PASS);
286 }
287