• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
62 #define _GNU_SOURCE
63 #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"
76 
77 char *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 
91 static void setup(void);
92 static void cleanup(void);
93 
94 struct test_case {
95 	char *desc;
96 	char *path;
97 	int flags;
98 	mode_t mode;
99 	int err;
100 };
101 struct 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 	},
164 	/*
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 
326 int TST_TOTAL = sizeof(tc) / sizeof(tc[0]);
327 
main(int argc,char * argv[])328 int main(int argc, char *argv[])
329 {
330 	int lc;
331 	int i;
332 	int fd;
333 	int ret;
334 
335 	tst_parse_opts(argc, argv, NULL, NULL);
336 
337 	setup();
338 
339 	for (lc = 0; TEST_LOOPING(lc); lc++) {
340 		for (i = 0; i < TST_TOTAL; i++) {
341 			TEST(open(tc[i].path, tc[i].flags, tc[i].mode));
342 			fd = TEST_RETURN;
343 
344 			if (tc[i].err == -1 || TEST_ERRNO == tc[i].err) {
345 				tst_resm(TPASS, "%s", tc[i].desc);
346 			} else {
347 				tst_resm(TFAIL | TTERRNO,
348 					 "%s - expected errno %d - Got",
349 					 tc[i].desc, tc[i].err);
350 			}
351 			if (fd > 0) {
352 				ret = close(fd);
353 				if (ret < 0)
354 					tst_resm(TWARN, "%s - close failed: %s",
355 						 tc[i].desc, strerror(errno));
356 			}
357 		}
358 	}
359 
360 	cleanup();
361 	tst_exit();
362 }
363 
setup(void)364 static void setup(void)
365 {
366 	int fd;
367 	int ret;
368 
369 	tst_require_root();
370 
371 	tst_tmpdir();
372 
373 	/* Create test files */
374 	fd = open(T_REG, O_WRONLY | O_CREAT, 0644);
375 	if (fd == -1)
376 		tst_brkm(TBROK | TERRNO, cleanup, "Create %s failed", T_REG);
377 	ret = write(fd, T_MSG, sizeof(T_MSG));
378 	if (ret == -1) {
379 		close(fd);
380 		tst_brkm(TBROK | TERRNO, cleanup, "Write %s failed", T_REG);
381 	}
382 	close(fd);
383 
384 	fd = creat(T_REG_EMPTY, 0644);
385 	if (fd == -1)
386 		tst_brkm(TBROK | TERRNO, cleanup, "Create %s failed",
387 			 T_REG_EMPTY);
388 	close(fd);
389 
390 	ret = link(T_REG, T_LINK_REG);
391 	if (ret == -1)
392 		tst_brkm(TBROK | TERRNO, cleanup, "Hard link %s -> %s failed",
393 			 T_REG, T_LINK_REG);
394 
395 	ret = symlink(T_REG, T_SYMLINK_REG);
396 	if (ret == -1)
397 		tst_brkm(TBROK | TERRNO, cleanup, "Symlink %s -> %s failed",
398 			 T_REG, T_SYMLINK_REG);
399 
400 	ret = mkdir(T_DIR, 0755);
401 	if (ret == -1)
402 		tst_brkm(TBROK | TERRNO, cleanup, "mkdir %s failed", T_DIR);
403 
404 	ret = symlink(T_DIR, T_SYMLINK_DIR);
405 	if (ret == -1)
406 		tst_brkm(TBROK | TERRNO, cleanup, "Symlink %s -> %s failed",
407 			 T_DIR, T_SYMLINK_DIR);
408 
409 	ret = mknod(T_DEV, S_IFCHR, makedev(1, 5));
410 	if (ret == -1)
411 		tst_brkm(TBROK | TERRNO, cleanup, "Create char dev %s failed",
412 			 T_DEV);
413 
414 	TEST_PAUSE;
415 }
416 
cleanup(void)417 static void cleanup(void)
418 {
419 	tst_rmdir();
420 }
421