1 /* test23: chdir(), getcwd() Author: Jan-Mark Wams (jms@cs.vu.nl) */ 2 3 #include <sys/types.h> 4 #include <sys/stat.h> 5 #include <limits.h> 6 #include <errno.h> 7 #include <unistd.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <fcntl.h> 11 #include <stdio.h> 12 13 int max_error = 4; 14 #include "common.h" 15 16 #define ITERATIONS 3 17 18 19 #define System(cmd) if (system(cmd) != 0) printf("``%s'' failed\n", cmd) 20 #define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir) 21 22 int subtest; 23 int superuser; /* True if we are root. */ 24 25 char cwd[PATH_MAX]; /* Space for path names. */ 26 char cwd2[PATH_MAX]; 27 char buf[PATH_MAX]; 28 char *MaxName; /* Name of maximum length */ 29 char MaxPath[PATH_MAX]; /* Same for path */ 30 char *ToLongName; /* Name of maximum +1 length */ 31 char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */ 32 33 void test23a(void); 34 void test23b(void); 35 void test23c(void); 36 void makelongnames(void); 37 38 int main(int argc, char *argv[]) 39 { 40 int i, m = 0xFFFF; 41 42 sync(); 43 if (argc == 2) m = atoi(argv[1]); 44 start(23); 45 makelongnames(); 46 superuser = (geteuid() == 0); 47 48 for (i = 0; i < ITERATIONS; i++) { 49 if (m & 0001) test23a(); /* Test normal operation */ 50 if (m & 0002) test23b(); /* Test critical operation */ 51 if (m & 0004) test23c(); /* Test error operation */ 52 } 53 54 quit(); 55 return 1; 56 } 57 58 void test23a() 59 { /* Test normal operation. */ 60 register int i; 61 62 subtest = 1; 63 64 System("rm -rf ../DIR_23/*"); 65 66 /* Let's do some fiddeling with path names. */ 67 if (getcwd(cwd, PATH_MAX) != cwd) e(1); 68 if (chdir(cwd) != 0) e(2); 69 if (getcwd(buf, PATH_MAX) != buf) e(3); 70 if (strcmp(buf, cwd) != 0) e(4); 71 if (chdir(".") != 0) e(5); 72 if (getcwd(buf, PATH_MAX) != buf) e(6); 73 if (strcmp(buf, cwd) != 0) e(7); 74 if (chdir("./././.") != 0) e(8); 75 if (getcwd(buf, PATH_MAX) != buf) e(9); 76 if (strcmp(buf, cwd) != 0) e(10); 77 78 /* Creat a working dir named "foo", remove any previous residues. */ 79 System("rm -rf foo"); 80 if (mkdir("foo", 0777) != 0) e(11); 81 82 /* Do some more fiddeling with path names. */ 83 if (chdir("foo/.././foo/..") != 0) e(12); /* change to cwd */ 84 if (getcwd(buf, PATH_MAX) != buf) e(13); 85 if (strcmp(buf, cwd) != 0) e(13); 86 if (chdir("foo") != 0) e(14); /* change to foo */ 87 if (chdir("..") != 0) e(15); /* and back again */ 88 if (getcwd(buf, PATH_MAX) != buf) e(16); 89 if (strcmp(buf, cwd) != 0) e(17); 90 91 /* Make 30 sub dirs, eg. ./bar/bar/bar/bar/bar...... */ 92 System("rm -rf bar"); /* get ridd of bar */ 93 for (i = 0; i < 30; i++) { 94 if (mkdir("bar", 0777) != 0) e(18); 95 if (chdir("bar") != 0) e(19); /* change to bar */ 96 } 97 for (i = 0; i < 30; i++) { 98 if (chdir("..") != 0) e(20); /* and back again */ 99 if (rmdir("bar") != 0) e(21); 100 } 101 102 /* Make sure we are back where we started. */ 103 if (getcwd(buf, PATH_MAX) != buf) e(22); 104 if (strcmp(buf, cwd) != 0) e(23); 105 System("rm -rf bar"); /* just incase */ 106 107 /* Do some normal checks on `Chdir()' and `getcwd()' */ 108 if (chdir("/") != 0) e(24); 109 if (getcwd(buf, PATH_MAX) != buf) e(25); 110 if (strcmp(buf, "/") != 0) e(26); 111 if (chdir("..") != 0) e(27); /* go to parent of / */ 112 if (getcwd(buf, PATH_MAX) != buf) e(28); 113 if (strcmp(buf, "/") != 0) e(29); 114 if (chdir(cwd) != 0) e(30); 115 if (getcwd(buf, PATH_MAX) != buf) e(31); 116 if (strcmp(buf, cwd) != 0) e(32); 117 if (chdir("/etc") != 0) e(33); /* /etc might be on RAM */ 118 if (getcwd(buf, PATH_MAX) != buf) e(34); /* might make a difference */ 119 if (strcmp(buf, "/etc") != 0) e(35); 120 if (chdir(cwd) != 0) e(36); 121 if (getcwd(buf, PATH_MAX) != buf) e(37); 122 if (strcmp(buf, cwd) != 0) e(38); 123 if (chdir(".//.//") != 0) e(39); /* .//.// == current dir */ 124 if (getcwd(buf, PATH_MAX) != buf) e(40); 125 if (strcmp(buf, cwd) != 0) e(41); /* we might be at '/' */ 126 System("rm -rf foo"); 127 } 128 129 void test23b() 130 { /* Test critical values. */ 131 int does_truncate; 132 subtest = 2; 133 134 System("rm -rf ../DIR_23/*"); 135 136 /* Fiddle with the size (2nd) parameter of `getcwd ()'. */ 137 if (getcwd(cwd, PATH_MAX) != cwd) e(1); /* get cwd */ 138 if (getcwd(buf, strlen(cwd)) != (char *) 0) e(2); /* size 1 to small */ 139 if (errno != ERANGE) e(3); 140 if (getcwd(buf, PATH_MAX) != buf) e(4); 141 if (strcmp(buf, cwd) != 0) e(5); 142 Chdir(cwd); /* getcwd might cd / */ 143 if (getcwd(buf, strlen(cwd) + 1) != buf) e(6); /* size just ok */ 144 if (getcwd(buf, PATH_MAX) != buf) e(7); 145 if (strcmp(buf, cwd) != 0) e(8); 146 147 /* Let's see how "MaxName" and "ToLongName" are handled. */ 148 if (mkdir(MaxName, 0777) != 0) e(9); 149 if (chdir(MaxName) != 0) e(10); 150 if (chdir("..") != 0) e(11); 151 if (rmdir(MaxName) != 0) e(12); 152 if (getcwd(buf, PATH_MAX) != buf) e(13); 153 if (strcmp(buf, cwd) != 0) e(14); 154 if (chdir(MaxPath) != 0) e(15); 155 if (getcwd(buf, PATH_MAX) != buf) e(16); 156 if (strcmp(buf, cwd) != 0) e(17); 157 158 does_truncate = does_fs_truncate(); 159 if (chdir(ToLongName) != -1) e(18); 160 if (does_truncate) { 161 if (errno != ENOENT) e(19); 162 } else { 163 if (errno != ENAMETOOLONG) e(20); 164 } 165 166 if (getcwd(buf, PATH_MAX) != buf) e(21); 167 if (strcmp(buf, cwd) != 0) e(22); 168 if (chdir(ToLongPath) != -1) e(23); 169 if (errno != ENAMETOOLONG) e(24); 170 if (getcwd(buf, PATH_MAX) != buf) e(25); 171 if (strcmp(buf, cwd) != 0) e(26); 172 } 173 174 void test23c() 175 { /* Check reaction to errors */ 176 subtest = 3; 177 178 System("rm -rf ../DIR_23/*"); 179 180 if (getcwd(cwd, PATH_MAX) != cwd) e(1); /* get cwd */ 181 182 /* Creat a working dir named "foo", remove any previous residues. */ 183 System("rm -rf foo; mkdir foo"); 184 185 /* Check some obviouse errors. */ 186 if (chdir("") != -1) e(2); 187 if (errno != ENOENT) e(3); 188 if (getcwd(buf, PATH_MAX) != buf) e(4); 189 if (strcmp(buf, cwd) != 0) e(5); 190 if (getcwd(buf, 0) != (char *) 0) e(6); 191 if (errno != EINVAL) e(7); 192 if (getcwd(buf, PATH_MAX) != buf) e(8); 193 if (strcmp(buf, cwd) != 0) e(9); 194 if (getcwd(buf, 0) != (char *) 0) e(10); 195 if (errno != EINVAL) e(11); 196 if (getcwd(buf, PATH_MAX) != buf) e(12); 197 if (strcmp(buf, cwd) != 0) e(13); 198 if (chdir(cwd) != 0) e(14); /* getcwd might be buggy. */ 199 200 /* Change the mode of foo, and check the effect. */ 201 if (chdir("foo") != 0) e(15); /* change to foo */ 202 if (mkdir("bar", 0777) != 0) e(16); /* make a new dir bar */ 203 if (getcwd(cwd2, PATH_MAX) != cwd2) e(17); /* get the new cwd */ 204 if (getcwd(buf, 3) != (char *) 0) e(18); /* size is too small */ 205 if (errno != ERANGE) e(19); 206 if (getcwd(buf, PATH_MAX) != buf) e(20); 207 if (strcmp(buf, cwd2) != 0) e(21); 208 Chdir(cwd2); /* getcwd() might cd / */ 209 System("chmod 377 ."); /* make foo unreadable */ 210 if (getcwd(buf, PATH_MAX) != buf) e(22); /* dir not readable */ 211 if (getcwd(buf, PATH_MAX) != buf) e(23); 212 if (strcmp(buf, cwd2) != 0) e(24); 213 if (chdir("bar") != 0) e(25); /* at .../foo/bar */ 214 if (!superuser) { 215 if (getcwd(buf, PATH_MAX) != (char *) 0) e(26); 216 if (errno != EACCES) e(27); 217 } 218 if (superuser) { 219 if (getcwd(buf, PATH_MAX) != buf) e(28); 220 } 221 if (chdir(cwd2) != 0) e(29); 222 if (getcwd(buf, PATH_MAX) != buf) e(30); 223 if (strcmp(buf, cwd2) != 0) e(31); 224 System("chmod 677 ."); /* make foo inaccessable */ 225 if (!superuser) { 226 if (getcwd(buf, PATH_MAX) != (char *) 0) e(32); /* try to get cwd */ 227 if (errno != EACCES) e(33); /* but no access */ 228 if (chdir("..") != -1) e(34); /* try to get back */ 229 if (errno != EACCES) e(35); /* again no access */ 230 if (chdir(cwd) != 0) e(36); /* get back to cwd */ 231 /* `Chdir()' might do path optimizing, it shouldn't. */ 232 if (chdir("foo/..") != -1) e(37); /* no op */ 233 if (chdir("foo") != -1) e(38); /* try to cd to foo */ 234 if (errno != EACCES) e(39); /* no have access */ 235 if (getcwd(buf, PATH_MAX) != buf) e(40); 236 if (strcmp(buf, cwd) != 0) e(41); 237 } 238 if (superuser) { 239 if (getcwd(buf, PATH_MAX) != buf) e(42); 240 if (strcmp(buf, cwd2) != 0) e(43); 241 if (chdir("..") != 0) e(44); /* get back to cwd */ 242 if (chdir("foo") != 0) e(45); /* get back to foo */ 243 if (chdir(cwd) != 0) e(46); /* get back to cwd */ 244 } 245 if (getcwd(buf, PATH_MAX) != buf) e(47); /* check we are */ 246 if (strcmp(buf, cwd) != 0) e(48); /* back at cwd. */ 247 Chdir(cwd); /* just in case... */ 248 249 if (chdir("/etc/passwd") != -1) e(49); /* try to change to a file */ 250 if (errno != ENOTDIR) e(50); 251 if (getcwd(buf, PATH_MAX) != buf) e(51); 252 if (strcmp(buf, cwd) != 0) e(52); 253 if (chdir("/notexist") != -1) e(53); 254 if (errno != ENOENT) e(54); 255 if (getcwd(buf, PATH_MAX) != buf) e(55); 256 if (strcmp(buf, cwd) != 0) e(56); 257 System("chmod 777 foo"); 258 if (chdir("foo") != 0) e(57); 259 260 /* XXX - this comment was botched by 'pretty'. */ 261 /* * Since `foo' is the cwd, it should not be removeable but * if it 262 * were, this code would be found here; * 263 * 264 * System ("cd .. ; rm -rf foo"); remove foo * if (chdir (".") 265 * != -1) e(); try go to. * if (errno != ENOENT) e(); 266 * hould not be an entry * if (chdir ("..") != -1) e(); try 267 * to get back * if (errno != ENOENT) e(); should not be 268 * an entry * if (getcwd (buf, PATH_MAX) != (char *)0) e(); don't 269 * know where we are * 270 * 271 * What should errno be now ? The cwd might be gone if te superuser * 272 * removed the cwd. (Might even have linked it first.) But this * 273 * testing should be done by the test program for `rmdir()'. */ 274 if (chdir(cwd) != 0) e(58); 275 } 276 277 void makelongnames() 278 { 279 register int i; 280 int max_name_length; 281 282 max_name_length = name_max("."); /* Aka NAME_MAX, but not every FS supports 283 * the same length, hence runtime check */ 284 MaxName = malloc(max_name_length + 1); 285 ToLongName = malloc(max_name_length + 1 + 1); /* Name of maximum +1 length */ 286 memset(MaxName, 'a', max_name_length); 287 MaxName[max_name_length] = '\0'; 288 289 for (i = 0; i < PATH_MAX - 1; i++) { /* idem path */ 290 MaxPath[i++] = '.'; 291 MaxPath[i] = '/'; 292 } 293 MaxPath[PATH_MAX - 1] = '\0'; 294 295 strcpy(ToLongName, MaxName); /* copy them Max to ToLong */ 296 strcpy(ToLongPath, MaxPath); 297 298 ToLongName[max_name_length] = 'a'; 299 ToLongName[max_name_length+1] = '\0';/* extend ToLongName by one too many */ 300 ToLongPath[PATH_MAX - 1] = '/'; 301 ToLongPath[PATH_MAX] = '\0'; /* inc ToLongPath by one */ 302 } 303 304