• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2001
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 /*
21  * NAME
22  *	open07.c
23  *
24  * DESCRIPTION
25  *	Test the open(2) system call to ensure that it sets ELOOP correctly.
26  *
27  * CALLS
28  *	open()
29  *
30  * ALGORITHM
31  *	1. Create a symbolic link to a file, and call open(O_NOFOLLOW). Check
32  *	   that it returns ELOOP.
33  *
34  *	2. Create a symbolic link to a directory, and call open(O_NOFOLLOW).
35  *	   Check that it returns ELOOP.
36  *
37  *	3. Create a symbolic link to a symbolic link, and call open(O_NOFOLLOW).
38  *	   Check that it returns ELOOP.
39  *
40  *	4. Create a symbolic link to a symbolically linked directory, and call
41  *	   open(O_NOFOLLOW). Check that it returns ELOOP.
42  *
43  *	5. Create a symbolic link to a directory, and call
44  *         open("link/", O_NOFOLLOW). Check that it succeeds.
45  *
46  * USAGE:  <for command-line>
47  *  open07 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
48  *     where,  -c n : Run n copies concurrently.
49  *             -e   : Turn on errno logging.
50  *             -i n : Execute test n times.
51  *             -I x : Execute test for x seconds.
52  *             -P x : Pause for x seconds between iterations.
53  *             -t   : Turn on syscall timing.
54  *
55  * HISTORY
56  *	07/2001 Ported by Wayne Boyer
57  *
58  * RESTRICTIONS
59  *	None
60  */
61 #define _GNU_SOURCE		/* for O_NOFOLLOW */
62 #include <stdio.h>
63 #include <errno.h>
64 #include <sys/types.h>
65 #include <sys/stat.h>
66 #include <fcntl.h>
67 #include "test.h"
68 
69 static void setup(void);
70 static void cleanup(void);
71 static void setupfunc_test1();
72 static void setupfunc_test2();
73 static void setupfunc_test3();
74 static void setupfunc_test4();
75 static void setupfunc_test5();
76 
77 char *TCID = "open07";
78 int TST_TOTAL = 5;
79 
80 static int fd1, fd2;
81 
82 static struct test_case_t {
83 	char *desc;
84 	char filename[100];
85 	int flags;
86 	int mode;
87 	void (*setupfunc) ();
88 	int exp_errno;
89 } TC[] = {
90 	{"Test for ELOOP on f2: f1 -> f2", {},
91 	 O_NOFOLLOW, 00700, setupfunc_test1, ELOOP},
92 	{"Test for ELOOP on d2: d1 -> d2", {},
93 	 O_NOFOLLOW, 00700, setupfunc_test2, ELOOP},
94 	{"Test for ELOOP on f3: f1 -> f2 -> f3", {},
95 	 O_NOFOLLOW, 00700, setupfunc_test3, ELOOP},
96 	{"Test for ELOOP on d3: d1 -> d2 -> d3", {},
97 	 O_NOFOLLOW, 00700, setupfunc_test4, ELOOP},
98 	{"Test for success on d2: d1 -> d2", {},
99 	 O_NOFOLLOW, 00700, setupfunc_test5, 0},
100 	{NULL, {}, 0, 0, NULL, 0}
101 };
102 
main(int ac,char ** av)103 int main(int ac, char **av)
104 {
105 	int lc;
106 	int i;
107 
108 	tst_parse_opts(ac, av, NULL, NULL);
109 
110 	setup();
111 
112 	/* run the setup routines for the individual tests */
113 	for (i = 0; i < TST_TOTAL; i++) {
114 		if (TC[i].setupfunc != NULL)
115 			TC[i].setupfunc();
116 	}
117 
118 	for (lc = 0; TEST_LOOPING(lc); lc++) {
119 		tst_count = 0;
120 
121 		for (i = 0; TC[i].desc != NULL; ++i) {
122 			TEST(open(TC[i].filename, TC[i].flags, TC[i].mode));
123 
124 			if (TC[i].exp_errno != 0) {
125 				if (TEST_RETURN != -1) {
126 					tst_resm(TFAIL, "open succeeded "
127 						 "unexpectedly");
128 				}
129 
130 				if (TEST_ERRNO != TC[i].exp_errno) {
131 					tst_resm(TFAIL, "open returned "
132 						 "unexpected errno, expected: "
133 						 "%d, got: %d",
134 						 TC[i].exp_errno, TEST_ERRNO);
135 				} else {
136 					tst_resm(TPASS, "open returned "
137 						 "expected ELOOP error");
138 				}
139 			} else {
140 				if (TEST_RETURN == -1) {
141 					tst_resm(TFAIL, "open failed "
142 						 "unexpectedly with errno %d",
143 						 TEST_ERRNO);
144 				} else {
145 					tst_resm(TPASS, "open succeeded as "
146 						 "expected");
147 				}
148 			}
149 
150 			if (TEST_RETURN != -1)
151 				close(TEST_RETURN);
152 		}
153 	}
154 
155 	cleanup();
156 	tst_exit();
157 }
158 
setupfunc_test1(void)159 static void setupfunc_test1(void)
160 {
161 	char file1[100], file2[100];
162 
163 	sprintf(file1, "open03.1.%d", getpid());
164 	sprintf(file2, "open03.2.%d", getpid());
165 	fd1 = creat(file1, 00700);
166 	if (fd1 < 0)
167 		tst_brkm(TBROK, cleanup, "creat(2) failed: errno: %d", errno);
168 
169 	if (symlink(file1, file2) < 0)
170 		tst_brkm(TBROK, cleanup, "symlink(2) failed: errno: %d", errno);
171 
172 	strcpy(TC[0].filename, file2);
173 }
174 
setupfunc_test2(void)175 static void setupfunc_test2(void)
176 {
177 	char file1[100], file2[100];
178 
179 	sprintf(file1, "open03.3.%d", getpid());
180 	sprintf(file2, "open03.4.%d", getpid());
181 	if (mkdir(file1, 00700) < 0)
182 		tst_brkm(TBROK, cleanup, "mkdir(2) failed: errno: %d", errno);
183 
184 	if (symlink(file1, file2) < 0)
185 		tst_brkm(TBROK, cleanup, "symlink(2) failed: errno: %d", errno);
186 
187 	strcpy(TC[1].filename, file2);
188 }
189 
setupfunc_test3(void)190 static void setupfunc_test3(void)
191 {
192 	char file1[100], file2[100], file3[100];
193 
194 	sprintf(file1, "open03.5.%d", getpid());
195 	sprintf(file2, "open03.6.%d", getpid());
196 	sprintf(file3, "open03.7.%d", getpid());
197 	fd2 = creat(file1, 00700);
198 	if (fd2 < 0)
199 		tst_brkm(TBROK, cleanup, "creat(2) failed: errno: %d", errno);
200 
201 	if (symlink(file1, file2) < 0)
202 		tst_brkm(TBROK, cleanup, "symlink(2) failed: errno: %d", errno);
203 
204 	if (symlink(file2, file3) < 0)
205 		tst_brkm(TBROK, cleanup, "symlink(2) failed: errno: %d", errno);
206 
207 	strcpy(TC[2].filename, file3);
208 }
209 
setupfunc_test4(void)210 static void setupfunc_test4(void)
211 {
212 	char file1[100], file2[100], file3[100];
213 
214 	sprintf(file1, "open03.8.%d", getpid());
215 	sprintf(file2, "open03.9.%d", getpid());
216 	sprintf(file3, "open03.10.%d", getpid());
217 	if (mkdir(file1, 00700) < 0)
218 		tst_brkm(TBROK, cleanup, "mkdir(2) failed: errno: %d", errno);
219 
220 	if (symlink(file1, file2) < 0)
221 		tst_brkm(TBROK, cleanup, "symlink(2) failed: errno: %d", errno);
222 
223 	if (symlink(file2, file3) < 0)
224 		tst_brkm(TBROK, cleanup, "symlink(2) failed: errno: %d", errno);
225 
226 	strcpy(TC[3].filename, file3);
227 }
228 
setupfunc_test5(void)229 static void setupfunc_test5(void)
230 {
231 	char file1[100], file2[100];
232 
233 	sprintf(file1, "open11.3.%d", getpid());
234 	sprintf(file2, "open12.4.%d", getpid());
235 	if (mkdir(file1, 00700) < 0)
236 		tst_brkm(TBROK, cleanup, "mkdir(2) failed: errno: %d", errno);
237 
238 	if (symlink(file1, file2) < 0)
239 		tst_brkm(TBROK, cleanup, "symlink(2) failed: errno: %d", errno);
240 
241 	strcpy(TC[4].filename, file2);
242 	strcat(TC[4].filename, "/");
243 }
244 
setup(void)245 static void setup(void)
246 {
247 	umask(0);
248 
249 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
250 
251 	TEST_PAUSE;
252 
253 	tst_tmpdir();
254 }
255 
cleanup(void)256 static void cleanup(void)
257 {
258 	close(fd1);
259 	close(fd2);
260 
261 	tst_rmdir();
262 }
263