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 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 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 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 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 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 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 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 256 static void cleanup(void) 257 { 258 close(fd1); 259 close(fd2); 260 261 tst_rmdir(); 262 } 263