blob: a04c834a14868da20bb07f08ce67ba7b27a51108 [file] [log] [blame]
Eryu Guan4d7e1882013-02-04 11:22:12 +08001/*
2 * Copyright (C) 2013 Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it
13 * is free of the rightful claim of any third person regarding
14 * infringement or the like. Any license provided herein, whether
15 * implied or otherwise, applies only to this software file. Patent
16 * licenses, if any, provided herein do not apply to combinations of
17 * this program with other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * 02110-1301, USA.
23 */
24
25/*
26 * Basic tests for open(2) and make sure open(2) works and handles error
27 * conditions correctly.
28 *
29 * There are 28 test cases:
30 * 1. Open regular file O_RDONLY
31 * 2. Open regular file O_WRONLY
32 * 3. Open regular file O_RDWR
33 * 4. Open regular file O_RDWR | O_SYNC
34 * 5. Open regular file O_RDWR | O_TRUNC
35 * 6. Open dir O_RDONLY
36 * 7. Open dir O_RDWR, expect EISDIR
37 * 8. Open regular file O_DIRECTORY, expect ENOTDIR
38 * 9. Open hard link file O_RDONLY
39 * 10. Open hard link file O_WRONLY
40 * 11. Open hard link file O_RDWR
41 * 12. Open sym link file O_RDONLY
42 * 13. Open sym link file O_WRONLY
43 * 14. Open sym link file O_RDWR
44 * 15. Open sym link dir O_RDONLY
45 * 16. Open sym link dir O_WRONLY, expect EISDIR
46 * 17. Open sym link dir O_RDWR, expect EISDIR
47 * 18. Open device special file O_RDONLY
48 * 19. Open device special file O_WRONLY
49 * 20. Open device special file O_RDWR
50 * 21. Open non-existing regular file in existing dir
51 * 22. Open link file O_RDONLY | O_CREAT
52 * 23. Open symlink file O_RDONLY | O_CREAT
53 * 24. Open regular file O_RDONLY | O_CREAT
54 * 25. Open symlink dir O_RDONLY | O_CREAT, expect EISDIR
55 * 26. Open dir O_RDONLY | O_CREAT, expect EISDIR
56 * 27. Open regular file O_RDONLY | O_TRUNC, behaviour is undefined but should
57 * not oops or hang
58 * 28. Open regular file(non-empty) O_RDONLY | O_TRUNC, behaviour is undefined
59 * but should not oops or hang
60 */
61
Markos Chandras0d0c6952013-02-13 13:19:05 +000062#define _GNU_SOURCE
Eryu Guan4d7e1882013-02-04 11:22:12 +080063#include "config.h"
64#include <sys/types.h>
65#include <sys/stat.h>
66#include <sys/wait.h>
67#include <errno.h>
68#include <fcntl.h>
69#include <unistd.h>
70#include <signal.h>
71#include <stdio.h>
72#include <stdlib.h>
73#include <string.h>
74
75#include "test.h"
Eryu Guan4d7e1882013-02-04 11:22:12 +080076
77char *TCID = "open11";
78
79/* Define test files */
80#define T_REG "t_reg" /* regular file with content */
81#define T_REG_EMPTY "t_reg_empty" /* empty regular file */
82#define T_LINK_REG "t_link_reg" /* hard link to T_REG */
83#define T_NEW_REG "t_new_reg" /* new regular file to be created */
84#define T_SYMLINK_REG "t_symlink_reg" /* symlink to T_REG */
85#define T_DIR "t_dir" /* test dir */
86#define T_SYMLINK_DIR "t_symlink_dir" /* symlink to T_DIR */
87#define T_DEV "t_dev" /* test device special file */
88
89#define T_MSG "this is a test string"
90
91static void setup(void);
92static void cleanup(void);
93
94struct test_case {
95 char *desc;
96 char *path;
97 int flags;
98 mode_t mode;
99 int err;
100};
101struct test_case tc[] = {
102 /*
103 * Test open(2) regular file
104 */
105 { /* open regular file O_RDONLY */
106 .desc = "Open regular file O_RDONLY",
107 .path = T_REG_EMPTY,
108 .flags = O_RDONLY,
109 .mode = 0644,
110 .err = 0,
111 },
112 { /* open regular file O_WRONLY */
113 .desc = "Open regular file O_WRONLY",
114 .path = T_REG_EMPTY,
115 .flags = O_WRONLY,
116 .mode = 0644,
117 .err = 0,
118 },
119 { /* open regular file O_RDWR */
120 .desc = "Open regular file O_RDWR",
121 .path = T_REG_EMPTY,
122 .flags = O_RDWR,
123 .mode = 0644,
124 .err = 0,
125 },
126 { /* open regular file O_RDWR | O_SYNC*/
127 .desc = "Open regular file O_RDWR | O_SYNC",
128 .path = T_REG_EMPTY,
129 .flags = O_RDWR | O_SYNC,
130 .mode = 0644,
131 .err = 0,
132 },
133 { /* open regular file O_RDWR | O_TRUNC */
134 .desc = "Open regular file O_RDWR | O_TRUNC",
135 .path = T_REG_EMPTY,
136 .flags = O_RDWR | O_TRUNC,
137 .mode = 0644,
138 .err = 0,
139 },
140 /*
141 * Test open(2) directory
142 */
143 { /* open dir O_RDONLY */
144 .desc = "Open dir O_RDONLY",
145 .path = T_DIR,
146 .flags = O_RDONLY,
147 .mode = 0755,
148 .err = 0,
149 },
150 { /* open dir O_RDWR */
151 .desc = "Open dir O_RDWR, expect EISDIR",
152 .path = T_DIR,
153 .flags = O_RDWR,
154 .mode = 0755,
155 .err = EISDIR,
156 },
157 { /* open regular file O_DIRECTORY */
158 .desc = "Open regular file O_DIRECTORY, expect ENOTDIR",
159 .path = T_REG_EMPTY,
160 .flags = O_RDONLY | O_DIRECTORY,
161 .mode = 0644,
162 .err = ENOTDIR,
163 },
Eryu Guan4d7e1882013-02-04 11:22:12 +0800164 /*
165 * Test open(2) hard link
166 */
167 { /* open hard link file O_RDONLY */
168 .desc = "Open hard link file O_RDONLY",
169 .path = T_LINK_REG,
170 .flags = O_RDONLY,
171 .mode = 0644,
172 .err = 0,
173 },
174 { /* open hard link file O_WRONLY */
175 .desc = "Open hard link file O_WRONLY",
176 .path = T_LINK_REG,
177 .flags = O_WRONLY,
178 .mode = 0644,
179 .err = 0,
180 },
181 { /* open hard link file O_RDWR */
182 .desc = "Open hard link file O_RDWR",
183 .path = T_LINK_REG,
184 .flags = O_RDWR,
185 .mode = 0644,
186 .err = 0,
187 },
188 /*
189 * Test open(2) sym link
190 */
191 { /* open sym link file O_RDONLY */
192 .desc = "Open sym link file O_RDONLY",
193 .path = T_SYMLINK_REG,
194 .flags = O_RDONLY,
195 .mode = 0644,
196 .err = 0,
197 },
198 { /* open sym link file O_WRONLY */
199 .desc = "Open sym link file O_WRONLY",
200 .path = T_SYMLINK_REG,
201 .flags = O_WRONLY,
202 .mode = 0644,
203 .err = 0,
204 },
205 { /* open sym link file O_RDWR */
206 .desc = "Open sym link file O_RDWR",
207 .path = T_SYMLINK_REG,
208 .flags = O_RDWR,
209 .mode = 0644,
210 .err = 0,
211 },
212 { /* open sym link dir O_RDONLY */
213 .desc = "Open sym link dir O_RDONLY",
214 .path = T_SYMLINK_DIR,
215 .flags = O_RDONLY,
216 .mode = 0644,
217 .err = 0,
218 },
219 { /* open sym link dir O_WRONLY */
220 .desc = "Open sym link dir O_WRONLY, expect EISDIR",
221 .path = T_SYMLINK_DIR,
222 .flags = O_WRONLY,
223 .mode = 0644,
224 .err = EISDIR,
225 },
226 { /* open sym link dir O_RDWR */
227 .desc = "Open sym link dir O_RDWR, expect EISDIR",
228 .path = T_SYMLINK_DIR,
229 .flags = O_RDWR,
230 .mode = 0644,
231 .err = EISDIR,
232 },
233 /*
234 * Test open(2) device special
235 */
236 { /* open device special file O_RDONLY */
237 .desc = "Open device special file O_RDONLY",
238 .path = T_DEV,
239 .flags = O_RDONLY,
240 .mode = 0644,
241 .err = 0,
242 },
243 { /* open device special file O_WRONLY */
244 .desc = "Open device special file O_WRONLY",
245 .path = T_DEV,
246 .flags = O_WRONLY,
247 .mode = 0644,
248 .err = 0,
249 },
250 { /* open device special file O_RDWR */
251 .desc = "Open device special file O_RDWR",
252 .path = T_DEV,
253 .flags = O_RDWR,
254 .mode = 0644,
255 .err = 0,
256 },
257 /*
258 * Test open(2) non-existing file
259 */
260 { /* open non-existing regular file in existing dir */
261 .desc = "Open non-existing regular file in existing dir",
262 .path = T_DIR"/"T_NEW_REG,
263 .flags = O_RDWR | O_CREAT,
264 .mode = 0644,
265 .err = 0,
266 },
267 /*
268 * test open(2) with O_CREAT
269 */
270 { /* open hard link file O_RDONLY | O_CREAT */
271 .desc = "Open link file O_RDONLY | O_CREAT",
272 .path = T_LINK_REG,
273 .flags = O_RDONLY | O_CREAT,
274 .mode = 0644,
275 .err = 0,
276 },
277 { /* open sym link file O_RDONLY | O_CREAT */
278 .desc = "Open symlink file O_RDONLY | O_CREAT",
279 .path = T_SYMLINK_REG,
280 .flags = O_RDONLY | O_CREAT,
281 .mode = 0644,
282 .err = 0,
283 },
284 { /* open regular file O_RDONLY | O_CREAT */
285 .desc = "Open regular file O_RDONLY | O_CREAT",
286 .path = T_REG_EMPTY,
287 .flags = O_RDONLY | O_CREAT,
288 .mode = 0644,
289 .err = 0,
290 },
291 { /* open symlink dir O_RDONLY | O_CREAT */
292 .desc = "Open symlink dir O_RDONLY | O_CREAT, expect EISDIR",
293 .path = T_SYMLINK_DIR,
294 .flags = O_RDONLY | O_CREAT,
295 .mode = 0644,
296 .err = EISDIR,
297 },
298 { /* open dir O_RDONLY | O_CREAT */
299 .desc = "Open dir O_RDONLY | O_CREAT, expect EISDIR",
300 .path = T_DIR,
301 .flags = O_RDONLY | O_CREAT,
302 .mode = 0644,
303 .err = EISDIR,
304 },
305 /*
306 * Other random open(2) tests
307 */
308 { /* open regular file O_RDONLY | O_TRUNC */
309 .desc = "Open regular file O_RDONLY | O_TRUNC, "
310 "behaviour is undefined but should not oops or hang",
311 .path = T_REG_EMPTY,
312 .flags = O_RDONLY | O_TRUNC,
313 .mode = 0644,
314 .err = -1,
315 },
316 { /* open regular(non-empty) file O_RDONLY | O_TRUNC */
317 .desc = "Open regular file(non-empty) O_RDONLY | O_TRUNC, "
318 "behaviour is undefined but should not oops or hang",
319 .path = T_REG,
320 .flags = O_RDONLY | O_TRUNC,
321 .mode = 0644,
322 .err = -1,
323 },
324};
325
326int TST_TOTAL = sizeof(tc) / sizeof(tc[0]);
327
328int main(int argc, char *argv[])
329{
330 int lc;
331 int i;
332 int fd;
333 int ret;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200334 const char *msg;
Eryu Guan4d7e1882013-02-04 11:22:12 +0800335
336 msg = parse_opts(argc, argv, NULL, NULL);
337 if (msg != NULL)
338 tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);
339
340 setup();
341
342 for (lc = 0; TEST_LOOPING(lc); lc++) {
343 for (i = 0; i < TST_TOTAL; i++) {
344 TEST(open(tc[i].path, tc[i].flags, tc[i].mode));
345 fd = TEST_RETURN;
346
347 if (tc[i].err == -1 || TEST_ERRNO == tc[i].err) {
348 tst_resm(TPASS, "%s", tc[i].desc);
349 } else {
350 tst_resm(TFAIL | TTERRNO,
351 "%s - expected errno %d - Got",
352 tc[i].desc, tc[i].err);
353 }
354 if (fd > 0) {
355 ret = close(fd);
356 if (ret < 0)
357 tst_resm(TWARN, "%s - close failed: %s",
358 tc[i].desc, strerror(errno));
359 }
360 }
361 }
362
363 cleanup();
364 tst_exit();
365}
366
367static void setup(void)
368{
369 int fd;
370 int ret;
371
372 tst_require_root(NULL);
373
374 tst_tmpdir();
375
376 /* Create test files */
377 fd = open(T_REG, O_WRONLY | O_CREAT, 0644);
378 if (fd == -1)
379 tst_brkm(TBROK | TERRNO, cleanup, "Create %s failed", T_REG);
380 ret = write(fd, T_MSG, sizeof(T_MSG));
381 if (ret == -1) {
382 close(fd);
383 tst_brkm(TBROK | TERRNO, cleanup, "Write %s failed", T_REG);
384 }
385 close(fd);
386
387 fd = creat(T_REG_EMPTY, 0644);
388 if (fd == -1)
389 tst_brkm(TBROK | TERRNO, cleanup, "Create %s failed",
390 T_REG_EMPTY);
391 close(fd);
392
393 ret = link(T_REG, T_LINK_REG);
394 if (ret == -1)
395 tst_brkm(TBROK | TERRNO, cleanup, "Hard link %s -> %s failed",
396 T_REG, T_LINK_REG);
397
398 ret = symlink(T_REG, T_SYMLINK_REG);
399 if (ret == -1)
400 tst_brkm(TBROK | TERRNO, cleanup, "Symlink %s -> %s failed",
401 T_REG, T_SYMLINK_REG);
402
403 ret = mkdir(T_DIR, 0755);
404 if (ret == -1)
405 tst_brkm(TBROK | TERRNO, cleanup, "mkdir %s failed", T_DIR);
406
407 ret = symlink(T_DIR, T_SYMLINK_DIR);
408 if (ret == -1)
409 tst_brkm(TBROK | TERRNO, cleanup, "Symlink %s -> %s failed",
410 T_DIR, T_SYMLINK_DIR);
411
412 ret = mknod(T_DEV, S_IFCHR, makedev(1, 5));
413 if (ret == -1)
414 tst_brkm(TBROK | TERRNO, cleanup, "Create char dev %s failed",
415 T_DEV);
416
417 TEST_PAUSE;
418}
419
420static void cleanup(void)
421{
Eryu Guan4d7e1882013-02-04 11:22:12 +0800422 tst_rmdir();
423}