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 #include "safe_macros.h" 69 70 static void setup(void); 71 static void cleanup(void); 72 static void setupfunc_test1(); 73 static void setupfunc_test2(); 74 static void setupfunc_test3(); 75 static void setupfunc_test4(); 76 static void setupfunc_test5(); 77 78 char *TCID = "open07"; 79 int TST_TOTAL = 5; 80 81 static int fd1, fd2; 82 83 static struct test_case_t { 84 char *desc; 85 char filename[100]; 86 int flags; 87 int mode; 88 void (*setupfunc) (); 89 int exp_errno; 90 } TC[] = { 91 {"Test for ELOOP on f2: f1 -> f2", {}, 92 O_NOFOLLOW, 00700, setupfunc_test1, ELOOP}, 93 {"Test for ELOOP on d2: d1 -> d2", {}, 94 O_NOFOLLOW, 00700, setupfunc_test2, ELOOP}, 95 {"Test for ELOOP on f3: f1 -> f2 -> f3", {}, 96 O_NOFOLLOW, 00700, setupfunc_test3, ELOOP}, 97 {"Test for ELOOP on d3: d1 -> d2 -> d3", {}, 98 O_NOFOLLOW, 00700, setupfunc_test4, ELOOP}, 99 {"Test for success on d2: d1 -> d2", {}, 100 O_NOFOLLOW, 00700, setupfunc_test5, 0}, 101 {NULL, {}, 0, 0, NULL, 0} 102 }; 103 104 int main(int ac, char **av) 105 { 106 int lc; 107 int i; 108 109 tst_parse_opts(ac, av, NULL, NULL); 110 111 setup(); 112 113 /* run the setup routines for the individual tests */ 114 for (i = 0; i < TST_TOTAL; i++) { 115 if (TC[i].setupfunc != NULL) 116 TC[i].setupfunc(); 117 } 118 119 for (lc = 0; TEST_LOOPING(lc); lc++) { 120 tst_count = 0; 121 122 for (i = 0; TC[i].desc != NULL; ++i) { 123 TEST(open(TC[i].filename, TC[i].flags, TC[i].mode)); 124 125 if (TC[i].exp_errno != 0) { 126 if (TEST_RETURN != -1) { 127 tst_resm(TFAIL, "open succeeded " 128 "unexpectedly"); 129 } 130 131 if (TEST_ERRNO != TC[i].exp_errno) { 132 tst_resm(TFAIL, "open returned " 133 "unexpected errno, expected: " 134 "%d, got: %d", 135 TC[i].exp_errno, TEST_ERRNO); 136 } else { 137 tst_resm(TPASS, "open returned " 138 "expected ELOOP error"); 139 } 140 } else { 141 if (TEST_RETURN == -1) { 142 tst_resm(TFAIL, "open failed " 143 "unexpectedly with errno %d", 144 TEST_ERRNO); 145 } else { 146 tst_resm(TPASS, "open succeeded as " 147 "expected"); 148 } 149 } 150 151 if (TEST_RETURN != -1) 152 close(TEST_RETURN); 153 } 154 } 155 156 cleanup(); 157 tst_exit(); 158 } 159 160 static void setupfunc_test1(void) 161 { 162 char file1[100], file2[100]; 163 164 sprintf(file1, "open03.1.%d", getpid()); 165 sprintf(file2, "open03.2.%d", getpid()); 166 fd1 = SAFE_CREAT(cleanup, file1, 00700); 167 168 SAFE_SYMLINK(cleanup, file1, file2); 169 170 strcpy(TC[0].filename, file2); 171 } 172 173 static void setupfunc_test2(void) 174 { 175 char file1[100], file2[100]; 176 177 sprintf(file1, "open03.3.%d", getpid()); 178 sprintf(file2, "open03.4.%d", getpid()); 179 SAFE_MKDIR(cleanup, file1, 00700); 180 181 SAFE_SYMLINK(cleanup, file1, file2); 182 183 strcpy(TC[1].filename, file2); 184 } 185 186 static void setupfunc_test3(void) 187 { 188 char file1[100], file2[100], file3[100]; 189 190 sprintf(file1, "open03.5.%d", getpid()); 191 sprintf(file2, "open03.6.%d", getpid()); 192 sprintf(file3, "open03.7.%d", getpid()); 193 fd2 = SAFE_CREAT(cleanup, file1, 00700); 194 195 SAFE_SYMLINK(cleanup, file1, file2); 196 197 SAFE_SYMLINK(cleanup, file2, file3); 198 199 strcpy(TC[2].filename, file3); 200 } 201 202 static void setupfunc_test4(void) 203 { 204 char file1[100], file2[100], file3[100]; 205 206 sprintf(file1, "open03.8.%d", getpid()); 207 sprintf(file2, "open03.9.%d", getpid()); 208 sprintf(file3, "open03.10.%d", getpid()); 209 SAFE_MKDIR(cleanup, file1, 00700); 210 211 SAFE_SYMLINK(cleanup, file1, file2); 212 213 SAFE_SYMLINK(cleanup, file2, file3); 214 215 strcpy(TC[3].filename, file3); 216 } 217 218 static void setupfunc_test5(void) 219 { 220 char file1[100], file2[100]; 221 222 sprintf(file1, "open11.3.%d", getpid()); 223 sprintf(file2, "open12.4.%d", getpid()); 224 SAFE_MKDIR(cleanup, file1, 00700); 225 226 SAFE_SYMLINK(cleanup, file1, file2); 227 228 strcpy(TC[4].filename, file2); 229 strcat(TC[4].filename, "/"); 230 } 231 232 static void setup(void) 233 { 234 umask(0); 235 236 tst_sig(NOFORK, DEF_HANDLER, cleanup); 237 238 TEST_PAUSE; 239 240 tst_tmpdir(); 241 } 242 243 static void cleanup(void) 244 { 245 close(fd1); 246 close(fd2); 247 248 tst_rmdir(); 249 } 250