xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/open/open11.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2013 Red Hat, Inc.
4  * Copyright (c) Linux Test Project, 2013-2022
5  */
6 
7 /*\
8  * [Description]
9  *
10  * Basic tests for open(2) and make sure open(2) works and handles error
11  * conditions correctly.
12  *
13  * There are 28 test cases:
14  *
15  * 1. Open regular file O_RDONLY
16  * 2. Open regular file O_WRONLY
17  * 3. Open regular file O_RDWR
18  * 4. Open regular file O_RDWR | O_SYNC
19  * 5. Open regular file O_RDWR | O_TRUNC
20  * 6. Open directory O_RDONLY
21  * 7. Open directory O_RDWR, expect EISDIR
22  * 8. Open regular file O_DIRECTORY, expect ENOTDIR
23  * 9. Open hard link file O_RDONLY
24  * 10. Open hard link file O_WRONLY
25  * 11. Open hard link file O_RDWR
26  * 12. Open symlink file O_RDONLY
27  * 13. Open symlink file O_WRONLY
28  * 14. Open symlink file O_RDWR
29  * 15. Open symlink directory O_RDONLY
30  * 16. Open symlink directory O_WRONLY, expect EISDIR
31  * 17. Open symlink directory O_RDWR, expect EISDIR
32  * 18. Open device special file O_RDONLY
33  * 19. Open device special file O_WRONLY
34  * 20. Open device special file O_RDWR
35  * 21. Open non-existing regular file in existing dir
36  * 22. Open link file O_RDONLY | O_CREAT
37  * 23. Open symlink file O_RDONLY | O_CREAT
38  * 24. Open regular file O_RDONLY | O_CREAT
39  * 25. Open symlink directory O_RDONLY | O_CREAT, expect EISDIR
40  * 26. Open directory O_RDONLY | O_CREAT, expect EISDIR
41  * 27. Open regular file O_RDONLY | O_TRUNC, behaviour is undefined but should
42  *     not oops or hang
43  * 28. Open regular file(non-empty) O_RDONLY | O_TRUNC, behaviour is undefined
44  *     but should not oops or hang
45  */
46 
47 #define _GNU_SOURCE
48 #include <errno.h>
49 #include <sys/sysmacros.h>
50 #include <sys/types.h>
51 #include <sys/stat.h>
52 #include <fcntl.h>
53 #include <unistd.h>
54 
55 #include "tst_test.h"
56 
57 #define MNTPOINT "mntpoint"
58 #define T_REG "t_reg"			/* regular file with content */
59 #define T_REG_EMPTY "t_reg_empty"	/* empty regular file */
60 #define T_LINK_REG "t_link_reg"		/* hard link to T_REG */
61 #define T_NEW_REG "t_new_reg"		/* new regular file to be created */
62 #define T_SYMLINK_REG "t_symlink_reg"	/* symlink to T_REG */
63 #define T_DIR "t_dir"			/* test directory */
64 #define T_SYMLINK_DIR "t_symlink_dir"	/* symlink to T_DIR */
65 #define T_DEV MNTPOINT"/t_dev"		/* test device special file */
66 
67 #define T_MSG "this is a test string"
68 
69 static struct test_case {
70 	char *desc;
71 	char *path;
72 	int flags;
73 	mode_t mode;
74 	int err;
75 } tc[] = {
76 	/* Test open(2) regular file */
77 	{
78 		.desc = "open regular file O_RDONLY",
79 		.path = T_REG_EMPTY,
80 		.flags = O_RDONLY,
81 		.mode = 0644,
82 	},
83 	{
84 		.desc = "open regular file O_WRONLY",
85 		.path = T_REG_EMPTY,
86 		.flags = O_WRONLY,
87 		.mode = 0644,
88 	},
89 	{
90 		.desc = "open regular file O_RDWR",
91 		.path = T_REG_EMPTY,
92 		.flags = O_RDWR,
93 		.mode = 0644,
94 	},
95 	{
96 		.desc = "open regular file O_RDWR | O_SYNC",
97 		.path = T_REG_EMPTY,
98 		.flags = O_RDWR | O_SYNC,
99 		.mode = 0644,
100 	},
101 	{
102 		.desc = "open regular file O_RDWR | O_TRUNC",
103 		.path = T_REG_EMPTY,
104 		.flags = O_RDWR | O_TRUNC,
105 		.mode = 0644,
106 	},
107 
108 	/* Test open(2) directory */
109 	{
110 		.desc = "open directory O_RDONLY",
111 		.path = T_DIR,
112 		.flags = O_RDONLY,
113 		.mode = 0755,
114 	},
115 	{
116 		.desc = "open directory O_RDWR",
117 		.path = T_DIR,
118 		.flags = O_RDWR,
119 		.mode = 0755,
120 		.err = EISDIR,
121 	},
122 	{
123 		.desc = "open regular file O_DIRECTORY",
124 		.path = T_REG_EMPTY,
125 		.flags = O_RDONLY | O_DIRECTORY,
126 		.mode = 0644,
127 		.err = ENOTDIR,
128 	},
129 	/* Test open(2) hard link */
130 	{
131 		.desc = "open hard link file O_RDONLY",
132 		.path = T_LINK_REG,
133 		.flags = O_RDONLY,
134 		.mode = 0644,
135 	},
136 	{
137 		.desc = "open hard link file O_WRONLY",
138 		.path = T_LINK_REG,
139 		.flags = O_WRONLY,
140 		.mode = 0644,
141 	},
142 	{
143 		.desc = "open hard link file O_RDWR",
144 		.path = T_LINK_REG,
145 		.flags = O_RDWR,
146 		.mode = 0644,
147 	},
148 
149 	/* Test open(2) symlink */
150 	{
151 		.desc = "open symlink file O_RDONLY",
152 		.path = T_SYMLINK_REG,
153 		.flags = O_RDONLY,
154 		.mode = 0644,
155 	},
156 	{
157 		.desc = "open symlink file O_WRONLY",
158 		.path = T_SYMLINK_REG,
159 		.flags = O_WRONLY,
160 		.mode = 0644,
161 	},
162 	{
163 		.desc = "open symlink file O_RDWR",
164 		.path = T_SYMLINK_REG,
165 		.flags = O_RDWR,
166 		.mode = 0644,
167 	},
168 	{
169 		.desc = "open symlink directory O_RDONLY",
170 		.path = T_SYMLINK_DIR,
171 		.flags = O_RDONLY,
172 		.mode = 0644,
173 	},
174 	{
175 		.desc = "open symlink directory O_WRONLY",
176 		.path = T_SYMLINK_DIR,
177 		.flags = O_WRONLY,
178 		.mode = 0644,
179 		.err = EISDIR,
180 	},
181 	{
182 		.desc = "open symlink directory O_RDWR",
183 		.path = T_SYMLINK_DIR,
184 		.flags = O_RDWR,
185 		.mode = 0644,
186 		.err = EISDIR,
187 	},
188 
189 	/* Test open(2) device special */
190 	{
191 		.desc = "open device special file O_RDONLY",
192 		.path = T_DEV,
193 		.flags = O_RDONLY,
194 		.mode = 0644,
195 	},
196 	{
197 		.desc = "open device special file O_WRONLY",
198 		.path = T_DEV,
199 		.flags = O_WRONLY,
200 		.mode = 0644,
201 	},
202 	{
203 		.desc = "open device special file O_RDWR",
204 		.path = T_DEV,
205 		.flags = O_RDWR,
206 		.mode = 0644,
207 	},
208 
209 	/* Test open(2) non-existing file */
210 	{
211 		.desc = "open non-existing regular file in existing dir",
212 		.path = T_DIR"/"T_NEW_REG,
213 		.flags = O_RDWR | O_CREAT,
214 		.mode = 0644,
215 	},
216 
217 	/* test open(2) with O_CREAT */
218 	{
219 		.desc = "open link file O_RDONLY | O_CREAT",
220 		.path = T_LINK_REG,
221 		.flags = O_RDONLY | O_CREAT,
222 		.mode = 0644,
223 	},
224 	{
225 		.desc = "open symlink file O_RDONLY | O_CREAT",
226 		.path = T_SYMLINK_REG,
227 		.flags = O_RDONLY | O_CREAT,
228 		.mode = 0644,
229 	},
230 	{
231 		.desc = "open regular file O_RDONLY | O_CREAT",
232 		.path = T_REG_EMPTY,
233 		.flags = O_RDONLY | O_CREAT,
234 		.mode = 0644,
235 	},
236 	{
237 		.desc = "open symlink directory O_RDONLY | O_CREAT",
238 		.path = T_SYMLINK_DIR,
239 		.flags = O_RDONLY | O_CREAT,
240 		.mode = 0644,
241 		.err = EISDIR,
242 	},
243 	{
244 		.desc = "open directory O_RDONLY | O_CREAT",
245 		.path = T_DIR,
246 		.flags = O_RDONLY | O_CREAT,
247 		.mode = 0644,
248 		.err = EISDIR,
249 	},
250 
251 	/* Other random open(2) tests */
252 	{
253 		.desc = "open regular file O_RDONLY | O_TRUNC, "
254 			"behaviour is undefined but should not oops or hang",
255 		.path = T_REG_EMPTY,
256 		.flags = O_RDONLY | O_TRUNC,
257 		.mode = 0644,
258 		.err = -1,
259 	},
260 	{
261 		.desc = "open regular file(non-empty) O_RDONLY | O_TRUNC, "
262 			"behaviour is undefined but should not oops or hang",
263 		.path = T_REG,
264 		.flags = O_RDONLY | O_TRUNC,
265 		.mode = 0644,
266 		.err = -1,
267 	},
268 };
269 
verify_open(unsigned int n)270 static void verify_open(unsigned int n)
271 {
272 	if (tc[n].err > 0) {
273 		TST_EXP_FAIL2(open(tc[n].path, tc[n].flags, tc[n].mode),
274 		             tc[n].err, "%s", tc[n].desc);
275 	} else if (tc[n].err == 0) {
276 		TST_EXP_FD(open(tc[n].path, tc[n].flags, tc[n].mode),
277 		           "%s", tc[n].desc);
278 	} else {
279 		TEST(open(tc[n].path, tc[n].flags, tc[n].mode));
280 		tst_res(TPASS, "%s", tc[n].desc);
281 	}
282 
283 	if (TST_RET > 0)
284 		SAFE_CLOSE(TST_RET);
285 }
286 
setup(void)287 static void setup(void)
288 {
289 	int fd;
290 	int ret;
291 
292 	fd = SAFE_OPEN(T_REG, O_WRONLY | O_CREAT, 0644);
293 	ret = write(fd, T_MSG, sizeof(T_MSG));
294 	if (ret == -1) {
295 		SAFE_CLOSE(fd);
296 		tst_brk(TBROK | TERRNO, "Write %s failed", T_REG);
297 	}
298 	SAFE_CLOSE(fd);
299 
300 	SAFE_TOUCH(T_REG_EMPTY, 0644, NULL);
301 	SAFE_LINK(T_REG, T_LINK_REG);
302 	SAFE_SYMLINK(T_REG, T_SYMLINK_REG);
303 	SAFE_MKDIR(T_DIR, 0755);
304 	SAFE_SYMLINK(T_DIR, T_SYMLINK_DIR);
305 	SAFE_MKNOD(T_DEV, S_IFCHR, makedev(1, 5));
306 }
307 
308 static struct tst_test test = {
309 	.tcnt = ARRAY_SIZE(tc),
310 	.setup = setup,
311 	.test = verify_open,
312 	.needs_devfs = 1,
313 	.mntpoint = MNTPOINT,
314 	.needs_root = 1,
315 };
316