1 /* POSIX test program (21). Author: Andy Tanenbaum */ 2 3 /* The following POSIX calls are tested: 4 * 5 * rename(), mkdir(), rmdir() 6 */ 7 8 #include <sys/types.h> 9 #include <sys/stat.h> 10 #include <errno.h> 11 #include <fcntl.h> 12 #include <limits.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include <unistd.h> 16 #include <stdio.h> 17 18 #define ITERATIONS 1 19 int max_error = 3; 20 #include "common.h" 21 22 23 24 int main(int argc, char *argv []); 25 void test21a(void); 26 void test21b(void); 27 void test21c(void); 28 void test21d(void); 29 void test21e(void); 30 void test21f(void); 31 void test21g(void); 32 void test21h(void); 33 void test21i(void); 34 void test21k(void); 35 void test21l(void); 36 void test21m(void); 37 void test21n(void); 38 void test21o(void); 39 int get_link(char *name); 40 41 int main(argc, argv) 42 int argc; 43 char *argv[]; 44 { 45 46 int i, m = 0xFFFF; 47 48 start(21); 49 50 if (argc == 2) m = atoi(argv[1]); 51 52 for (i = 0; i < ITERATIONS; i++) { 53 if (m & 00001) test21a(); 54 if (m & 00002) test21b(); 55 if (m & 00004) test21c(); 56 if (m & 00010) test21d(); 57 if (m & 00020) test21e(); 58 if (m & 00040) test21f(); 59 if (m & 01000) test21g(); 60 if (m & 00200) test21h(); 61 if (m & 00400) test21i(); 62 if (m & 01000) test21k(); 63 if (m & 02000) test21l(); 64 if (m & 04000) test21m(); 65 if (m & 010000) test21n(); 66 if (m & 020000) test21o(); 67 } 68 quit(); 69 70 return(-1); /* Unreachable */ 71 } 72 73 void test21a() 74 { 75 /* Test rename(). */ 76 77 int fd, fd2; 78 char buf[PATH_MAX+1], buf1[PATH_MAX+1], buf2[PATH_MAX+1]; 79 struct stat stat1, stat2; 80 81 subtest = 1; 82 83 unlink("A1"); /* get rid of it if it exists */ 84 unlink("A2"); /* get rid of it if it exists */ 85 unlink("A3"); /* get rid of it if it exists */ 86 unlink("A4"); /* get rid of it if it exists */ 87 unlink("A5"); /* get rid of it if it exists */ 88 unlink("A6"); /* get rid of it if it exists */ 89 unlink("A7"); /* get rid of it if it exists */ 90 91 /* Basic test. Rename A1 to A2 and then A2 to A3. */ 92 if ( (fd=creat("A1", 0666)) < 0) e(1); 93 if (write(fd, buf, 20) != 20) e(2); 94 if (close(fd) < 0) e(3); 95 if (rename("A1", "A2") < 0) e(4); 96 if ( (fd=open("A2", O_RDONLY)) < 0) e(5); 97 if (rename("A2", "A3") < 0) e(6); 98 if ( (fd2=open("A3", O_RDONLY)) < 0) e(7); 99 if (close(fd) != 0) e(8); 100 if (close(fd2) != 0) e(9); 101 if (unlink("A3") != 0) e(10); 102 103 /* Now get the absolute path name of the current directory using getcwd() 104 * and use it to test RENAME using different combinations of relative and 105 * absolute path names. 106 */ 107 if (getcwd(buf, PATH_MAX) == (char *) NULL) e(11); 108 if ( (fd = creat("A4", 0666)) < 0) e(12); 109 if (write(fd, buf, 30) != 30) e(13); 110 if (close(fd) != 0) e(14); 111 strcpy(buf1, buf); 112 strcat(buf1, "/A4"); 113 if (rename(buf1, "A5") != 0) e(15); /* rename(absolute, relative) */ 114 if (access("A5", 6) != 0) e(16); /* use access to see if file exists */ 115 strcpy(buf2, buf); 116 strcat(buf2, "/A6"); 117 if (rename("A5", buf2) != 0) e(17); /* rename(relative, absolute) */ 118 if (access("A6", 6) != 0) e(18); 119 if (access(buf2, 6) != 0) e(19); 120 strcpy(buf1, buf); 121 strcat(buf1, "/A6"); 122 strcpy(buf2, buf); 123 strcat(buf2, "/A7"); 124 if (rename(buf1, buf2) != 0) e(20); /* rename(absolute, absolute) */ 125 if (access("A7", 6) != 0) e(21); 126 if (access(buf2, 6) != 0) e(22); 127 128 /* Try renaming using names like "./A8" */ 129 if (rename("A7", "./A8") != 0) e(23); 130 if (access("A8", 6) != 0) e(24); 131 if (rename("./A8", "A9") != 0) e(25); 132 if (access("A9", 6) != 0) e(26); 133 if (rename("./A9", "./A10") != 0) e(27); 134 if (access("A10", 6) != 0) e(28); 135 if (access("./A10", 6) != 0) e(29); 136 if (unlink("A10") != 0) e(30); 137 138 /* Now see if directories can be renamed. */ 139 if (system("rm -rf ?uzzy scsi") != 0) e(31); 140 if (system("mkdir fuzzy") != 0) e(32); 141 if (rename("fuzzy", "wuzzy") != 0) e(33); 142 if ( (fd=creat("wuzzy/was_a_bear", 0666)) < 0) e(34); 143 if (access("wuzzy/was_a_bear", 6) != 0) e(35); 144 if (unlink("wuzzy/was_a_bear") != 0) e(36); 145 if (close(fd) != 0) e(37); 146 if (rename("wuzzy", "buzzy") != 0) e(38); 147 if (system("rmdir buzzy") != 0) e(39); 148 149 /* Now start testing the case that 'new' exists. */ 150 if ( (fd = creat("horse", 0666)) < 0) e(40); 151 if ( (fd2 = creat("sheep", 0666)) < 0) e(41); 152 if (write(fd, buf, PATH_MAX) != PATH_MAX) e(42); 153 if (write(fd2, buf, 23) != 23) e(43); 154 if (stat("horse", &stat1) != 0) e(44); 155 if (rename("horse", "sheep") != 0) e(45); 156 if (stat("sheep", &stat2) != 0) e(46); 157 if (stat1.st_dev != stat2.st_dev) e(47); 158 if (stat1.st_ino != stat2.st_ino) e(48); 159 if (stat2.st_size != PATH_MAX) e(49); 160 if (access("horse", 6) == 0) e(50); 161 if (close(fd) != 0) e(51); 162 if (close(fd2) != 0) e(52); 163 if (rename("sheep", "sheep") != 0) e(53); 164 if (unlink("sheep") != 0) e(54); 165 166 /* Now try renaming something to a directory that already exists. */ 167 if (system("mkdir fuzzy wuzzy") != 0) e(55); 168 if ( (fd = creat("fuzzy/was_a_bear", 0666)) < 0) e(56); 169 if (close(fd) != 0) e(57); 170 if (rename("fuzzy", "wuzzy") != 0) e(58); /* 'new' is empty dir */ 171 if (system("mkdir scsi") != 0) e(59); 172 if (rename("scsi", "wuzzy") == 0) e(60); /* 'new' is full dir */ 173 if (errno != EEXIST && errno != ENOTEMPTY) e(61); 174 175 /* Test 14 character names--always tricky. */ 176 if (rename("wuzzy/was_a_bear", "wuzzy/was_not_a_bear") != 0) e(62); 177 if (access("wuzzy/was_not_a_bear", 6) != 0) e(63); 178 if (rename("wuzzy/was_not_a_bear", "wuzzy/was_not_a_duck") != 0) e(64); 179 if (access("wuzzy/was_not_a_duck", 6) != 0) e(65); 180 if (rename("wuzzy/was_not_a_duck", "wuzzy/was_a_bird") != 0) e(65); 181 if (access("wuzzy/was_a_bird", 6) != 0) e(66); 182 183 /* Test moves between directories. */ 184 if (rename("wuzzy/was_a_bird", "beast") != 0) e(67); 185 if (access("beast", 6) != 0) e(68); 186 if (rename("beast", "wuzzy/was_a_cat") != 0) e(69); 187 if (access("wuzzy/was_a_cat", 6) != 0) e(70); 188 189 /* Test error conditions. 'scsi' and 'wuzzy/was_a_cat' exist now. */ 190 if (rename("wuzzy/was_a_cat", "wuzzy/was_a_dog") != 0) e(71); 191 if (access("wuzzy/was_a_dog", 6) != 0) e(72); 192 if (chmod("wuzzy", 0) != 0) e(73); 193 194 errno = 0; 195 if (rename("wuzzy/was_a_dog", "wuzzy/was_a_pig") != -1) e(74); 196 if (errno != EACCES) e(75); 197 198 errno = 0; 199 if (rename("wuzzy/was_a_dog", "doggie") != -1) e(76); 200 if (errno != EACCES) e(77); 201 202 errno = 0; 203 if ( (fd = creat("beast", 0666)) < 0) e(78); 204 if (close(fd) != 0) e(79); 205 if (rename("beast", "wuzzy/was_a_twit") != -1) e(80); 206 if (errno != EACCES) e(81); 207 208 errno = 0; 209 if (rename("beast", "wuzzy") != -1) e(82); 210 if (errno != EISDIR) e(83); 211 212 errno = 0; 213 if (rename("beest", "baste") != -1) e(84); 214 if (errno != ENOENT) e(85); 215 216 errno = 0; 217 if (rename("wuzzy", "beast") != -1) e(86); 218 if (errno != ENOTDIR) e(87); 219 220 /* Test prefix rule. */ 221 errno = 0; 222 if (chmod("wuzzy", 0777) != 0) e(88); 223 if (unlink("wuzzy/was_a_dog") != 0) e(89); 224 strcpy(buf1, buf); 225 strcat(buf1, "/wuzzy"); 226 if (rename(buf, buf1) != -1) e(90); 227 if (errno != EINVAL) e(91); 228 229 if (system("rm -rf wuzzy beast scsi") != 0) e(92); 230 } 231 232 233 234 void test21b() 235 { 236 /* Test mkdir() and rmdir(). */ 237 238 int i; 239 char name[3]; 240 struct stat statbuf; 241 242 subtest = 2; 243 244 /* Simple stuff. */ 245 if (mkdir("D1", 0700) != 0) e(1); 246 if (stat("D1", &statbuf) != 0) e(2); 247 if (!S_ISDIR(statbuf.st_mode)) e(3); 248 if ( (statbuf.st_mode & 0777) != 0700) e(4); 249 if (rmdir("D1") != 0) e(5); 250 251 /* Make and remove 40 directories. By doing so, the directory has to 252 * grow to 2 blocks. That presents plenty of opportunity for bugs. 253 */ 254 name[0] = 'D'; 255 name[2] = '\0'; 256 for (i = 0; i < 40; i++) { 257 name[1] = 'A' + i; 258 if (mkdir(name, 0700 + i%7) != 0) e(10+i); /* for simplicity */ 259 } 260 for (i = 0; i < 40; i++) { 261 name[1] = 'A' + i; 262 if (rmdir(name) != 0) e(50+i); 263 } 264 } 265 266 void test21c() 267 { 268 /* Test mkdir() and rmdir(). */ 269 270 subtest = 3; 271 272 if (mkdir("D1", 0777) != 0) e(1); 273 if (mkdir("D1/D2", 0777) != 0) e(2); 274 if (mkdir("D1/D2/D3", 0777) != 0) e(3); 275 if (mkdir("D1/D2/D3/D4", 0777) != 0) e(4); 276 if (mkdir("D1/D2/D3/D4/D5", 0777) != 0) e(5); 277 if (mkdir("D1/D2/D3/D4/D5/D6", 0777) != 0) e(6); 278 if (mkdir("D1/D2/D3/D4/D5/D6/D7", 0777) != 0) e(7); 279 if (mkdir("D1/D2/D3/D4/D5/D6/D7/D8", 0777) != 0) e(8); 280 if (mkdir("D1/D2/D3/D4/D5/D6/D7/D8/D9", 0777) != 0) e(9); 281 if (access("D1/D2/D3/D4/D5/D6/D7/D8/D9", 7) != 0) e(10); 282 if (rmdir("D1/D2/D3/D4/D5/D6/D7/D8/D9") != 0) e(11); 283 if (rmdir("D1/D2/D3/D4/D5/D6/D7/D8") != 0) e(12); 284 if (rmdir("D1/D2/D3/D4/D5/D6/D7") != 0) e(13); 285 if (rmdir("D1/D2/D3/D4/D5/D6") != 0) e(11); 286 if (rmdir("D1/D2/D3/D4/D5") != 0) e(13); 287 if (rmdir("D1/D2/D3/D4") != 0) e(14); 288 if (rmdir("D1/D2/D3") != 0) e(15); 289 if (rmdir("D1/D2") != 0) e(16); 290 if (rmdir("D1") != 0) e(17); 291 } 292 293 void test21d() 294 { 295 /* Test making directories with files and directories in them. */ 296 297 int fd1, fd2, fd3, fd4, fd5, fd6, fd7, fd8, fd9; 298 299 subtest = 4; 300 301 if (mkdir("D1", 0777) != 0) e(1); 302 if (mkdir("D1/D2", 0777) != 0) e(2); 303 if (mkdir("./D1/D3", 0777) != 0) e(3); 304 if (mkdir("././D1/D4", 0777) != 0) e(4); 305 if ( (fd1 = creat("D1/D2/x", 0700)) < 0) e(5); 306 if ( (fd2 = creat("D1/D2/y", 0700)) < 0) e(6); 307 if ( (fd3 = creat("D1/D2/z", 0700)) < 0) e(7); 308 if ( (fd4 = creat("D1/D3/x", 0700)) < 0) e(8); 309 if ( (fd5 = creat("D1/D3/y", 0700)) < 0) e(9); 310 if ( (fd6 = creat("D1/D3/z", 0700)) < 0) e(10); 311 if ( (fd7 = creat("D1/D4/x", 0700)) < 0) e(11); 312 if ( (fd8 = creat("D1/D4/y", 0700)) < 0) e(12); 313 if ( (fd9 = creat("D1/D4/z", 0700)) < 0) e(13); 314 if (unlink("D1/D2/z") != 0) e(14); 315 if (unlink("D1/D2/y") != 0) e(15); 316 if (unlink("D1/D2/x") != 0) e(16); 317 if (unlink("D1/D3/x") != 0) e(17); 318 if (unlink("D1/D3/z") != 0) e(18); 319 if (unlink("D1/D3/y") != 0) e(19); 320 if (unlink("D1/D4/y") != 0) e(20); 321 if (unlink("D1/D4/z") != 0) e(21); 322 if (unlink("D1/D4/x") != 0) e(22); 323 if (rmdir("D1/D2") != 0) e(23); 324 if (rmdir("D1/D3") != 0) e(24); 325 if (rmdir("D1/D4") != 0) e(25); 326 if (rmdir("D1") != 0) e(26); 327 if (close(fd1) != 0) e(27); 328 if (close(fd2) != 0) e(28); 329 if (close(fd3) != 0) e(29); 330 if (close(fd4) != 0) e(30); 331 if (close(fd5) != 0) e(31); 332 if (close(fd6) != 0) e(32); 333 if (close(fd7) != 0) e(33); 334 if (close(fd8) != 0) e(34); 335 if (close(fd9) != 0) e(35); 336 337 } 338 339 void test21e() 340 { 341 /* Test error conditions. */ 342 343 subtest = 5; 344 345 if (mkdir("D1", 0677) != 0) e(1); 346 errno = 0; 347 if (mkdir("D1/D2", 0777) != -1) e(2); 348 if (errno != EACCES) e(3); 349 if (chmod ("D1", 0577) != 0) e(4); 350 errno = 0; 351 if (mkdir("D1/D2", 0777) != -1) e(5); 352 if (errno != EACCES) e(6); 353 if (chmod ("D1", 0777) != 0) e(7); 354 errno = 0; 355 if (mkdir("D1", 0777) != -1) e(8); 356 if (errno != EEXIST) e(9); 357 errno = 0; 358 if (mkdir("D1/D2/x", 0777) != -1) e(14); 359 if (errno != ENOENT) e(15); 360 361 /* A particularly nasty test is when the parent has mode 0. Although 362 * this is unlikely to work, it had better not muck up the file system 363 */ 364 if (mkdir("D1/D2", 0777) != 0) e(16); 365 if (chmod("D1", 0) != 0) e(17); 366 errno = 0; 367 if (rmdir("D1/D2") != -1) e(18); 368 if (errno != EACCES) e(19); 369 if (chmod("D1", 0777) != 0) e(20); 370 if (rmdir("D1/D2") != 0) e(21); 371 if (rmdir("D1") != 0) e(22); 372 } 373 374 void test21f() 375 { 376 /* The rename() function affects the link count of all the files and 377 * directories it goes near. Test to make sure it gets everything ok. 378 * There are four cases: 379 * 380 * 1. rename("d1/file1", "d1/file2"); - rename file without moving it 381 * 2. rename("d1/file1", "d2/file2"); - move a file to another dir 382 * 3. rename("d1/dir1", "d2/dir2"); - rename a dir without moving it 383 * 4. rename("d1/dir1", "d2/dir2"); - move a dir to another dir 384 * 385 * Furthermore, a distinction has to be made when the target file exists 386 * and when it does not exist, giving 8 cases in all. 387 */ 388 389 int fd, D1_before, D1_after, x_link, y_link; 390 391 /* Test case 1: renaming a file within the same directory. */ 392 subtest = 6; 393 if (mkdir("D1", 0777) != 0) e(1); 394 if ( (fd = creat("D1/x", 0777)) < 0) e(2); 395 if (close(fd) != 0) e(3); 396 D1_before = get_link("D1"); 397 x_link = get_link("D1/x"); 398 if (rename("D1/x", "D1/y") != 0) e(4); 399 y_link = get_link("D1/y"); 400 D1_after = get_link("D1"); 401 if (D1_before != 2) e(5); 402 if (D1_after != 2) e(6); 403 if (x_link != 1) e(7); 404 if (y_link != 1) e(8); 405 if (access("D1/y", 7) != 0) e(9); 406 if (unlink("D1/y") != 0) e(10); 407 if (rmdir("D1") != 0) e(11); 408 } 409 410 void test21g() 411 { 412 int fd, D1_before, D1_after, D2_before, D2_after, x_link, y_link; 413 414 /* Test case 2: move a file to a new directory. */ 415 subtest = 7; 416 if (mkdir("D1", 0777) != 0) e(1); 417 if (mkdir("D2", 0777) != 0) e(2); 418 if ( (fd = creat("D1/x", 0777)) < 0) e(3); 419 if (close(fd) != 0) e(4); 420 D1_before = get_link("D1"); 421 D2_before = get_link("D2"); 422 x_link = get_link("D1/x"); 423 if (rename("D1/x", "D2/y") != 0) e(5); 424 y_link = get_link("D2/y"); 425 D1_after = get_link("D1"); 426 D2_after = get_link("D2"); 427 if (D1_before != 2) e(6); 428 if (D2_before != 2) e(7); 429 if (D1_after != 2) e(8); 430 if (D2_after != 2) e(9); 431 if (x_link != 1) e(10); 432 if (y_link != 1) e(11); 433 if (access("D2/y", 7) != 0) e(12); 434 if (unlink("D2/y") != 0) e(13); 435 if (rmdir("D1") != 0) e(14); 436 if (rmdir("D2") != 0) e(15); 437 } 438 439 void test21h() 440 { 441 int D1_before, D1_after, x_link, y_link; 442 443 /* Test case 3: renaming a directory within the same directory. */ 444 subtest = 8; 445 if (mkdir("D1", 0777) != 0) e(1); 446 if (mkdir("D1/X", 0777) != 0) e(2); 447 D1_before = get_link("D1"); 448 x_link = get_link("D1/X"); 449 if (rename("D1/X", "D1/Y") != 0) e(3); 450 y_link = get_link("D1/Y"); 451 D1_after = get_link("D1"); 452 if (D1_before != 3) e(4); 453 if (D1_after != 3) e(5); 454 if (x_link != 2) e(6); 455 if (y_link != 2) e(7); 456 if (access("D1/Y", 7) != 0) e(8); 457 if (rmdir("D1/Y") != 0) e(9); 458 if (get_link("D1") != 2) e(10); 459 if (rmdir("D1") != 0) e(11); 460 } 461 462 void test21i() 463 { 464 int D1_before, D1_after, D2_before, D2_after, x_link, y_link; 465 466 /* Test case 4: move a directory to a new directory. */ 467 subtest = 9; 468 if (mkdir("D1", 0777) != 0) e(1); 469 if (mkdir("D2", 0777) != 0) e(2); 470 if (mkdir("D1/X", 0777) != 0) e(3); 471 D1_before = get_link("D1"); 472 D2_before = get_link("D2"); 473 x_link = get_link("D1/X"); 474 if (rename("D1/X", "D2/Y") != 0) e(4); 475 y_link = get_link("D2/Y"); 476 D1_after = get_link("D1"); 477 D2_after = get_link("D2"); 478 if (D1_before != 3) e(5); 479 if (D2_before != 2) e(6); 480 if (D1_after != 2) e(7); 481 if (D2_after != 3) e(8); 482 if (x_link != 2) e(9); 483 if (y_link != 2) e(10); 484 if (access("D2/Y", 7) != 0) e(11); 485 if (rename("D2/Y", "D1/Z") != 0) e(12); 486 if (get_link("D1") != 3) e(13); 487 if (get_link("D2") != 2) e(14); 488 if (rmdir("D1/Z") != 0) e(15); 489 if (get_link("D1") != 2) e(16); 490 if (rmdir("D1") != 0) e(17); 491 if (rmdir("D2") != 0) e(18); 492 } 493 494 void test21k() 495 { 496 /* Now test the same 4 cases, except when the target exists. */ 497 498 int fd, D1_before, D1_after, x_link, y_link; 499 500 /* Test case 5: renaming a file within the same directory. */ 501 subtest = 10; 502 if (mkdir("D1", 0777) != 0) e(1); 503 if ( (fd = creat("D1/x", 0777)) < 0) e(2); 504 if (close(fd) != 0) e(3); 505 if ( (fd = creat("D1/y", 0777)) < 0) e(3); 506 if (close(fd) != 0) e(4); 507 D1_before = get_link("D1"); 508 x_link = get_link("D1/x"); 509 if (rename("D1/x", "D1/y") != 0) e(5); 510 y_link = get_link("D1/y"); 511 D1_after = get_link("D1"); 512 if (D1_before != 2) e(6); 513 if (D1_after != 2) e(7); 514 if (x_link != 1) e(8); 515 if (y_link != 1) e(9); 516 if (access("D1/y", 7) != 0) e(10); 517 if (unlink("D1/y") != 0) e(11); 518 if (rmdir("D1") != 0) e(12); 519 } 520 521 void test21l() 522 { 523 int fd, D1_before, D1_after, D2_before, D2_after, x_link, y_link; 524 525 /* Test case 6: move a file to a new directory. */ 526 subtest = 11; 527 if (mkdir("D1", 0777) != 0) e(1); 528 if (mkdir("D2", 0777) != 0) e(2); 529 if ( (fd = creat("D1/x", 0777)) < 0) e(3); 530 if (close(fd) != 0) e(4); 531 if ( (fd = creat("D2/y", 0777)) < 0) e(5); 532 if (close(fd) != 0) e(6); 533 D1_before = get_link("D1"); 534 D2_before = get_link("D2"); 535 x_link = get_link("D1/x"); 536 if (rename("D1/x", "D2/y") != 0) e(7); 537 y_link = get_link("D2/y"); 538 D1_after = get_link("D1"); 539 D2_after = get_link("D2"); 540 if (D1_before != 2) e(8); 541 if (D2_before != 2) e(9); 542 if (D1_after != 2) e(10); 543 if (D2_after != 2) e(11); 544 if (x_link != 1) e(12); 545 if (y_link != 1) e(13); 546 if (access("D2/y", 7) != 0) e(14); 547 if (unlink("D2/y") != 0) e(15); 548 if (rmdir("D1") != 0) e(16); 549 if (rmdir("D2") != 0) e(17); 550 } 551 552 void test21m() 553 { 554 int D1_before, D1_after, x_link, y_link; 555 556 /* Test case 7: renaming a directory within the same directory. */ 557 subtest = 12; 558 if (mkdir("D1", 0777) != 0) e(1); 559 if (mkdir("D1/X", 0777) != 0) e(2); 560 if (mkdir("D1/Y", 0777) != 0) e(3); 561 D1_before = get_link("D1"); 562 x_link = get_link("D1/X"); 563 if (rename("D1/X", "D1/Y") != 0) e(4); 564 y_link = get_link("D1/Y"); 565 D1_after = get_link("D1"); 566 if (D1_before != 4) e(5); 567 if (D1_after != 3) e(6); 568 if (x_link != 2) e(7); 569 if (y_link != 2) e(8); 570 if (access("D1/Y", 7) != 0) e(9); 571 if (rmdir("D1/Y") != 0) e(10); 572 if (get_link("D1") != 2) e(11); 573 if (rmdir("D1") != 0) e(12); 574 } 575 576 void test21n() 577 { 578 int D1_before, D1_after, D2_before, D2_after, x_link, y_link; 579 580 /* Test case 8: move a directory to a new directory. */ 581 subtest = 13; 582 if (mkdir("D1", 0777) != 0) e(1); 583 if (mkdir("D2", 0777) != 0) e(2); 584 if (mkdir("D1/X", 0777) != 0) e(3); 585 if (mkdir("D2/Y", 0777) != 0) e(4); 586 D1_before = get_link("D1"); 587 D2_before = get_link("D2"); 588 x_link = get_link("D1/X"); 589 if (rename("D1/X", "D2/Y") != 0) e(5); 590 y_link = get_link("D2/Y"); 591 D1_after = get_link("D1"); 592 D2_after = get_link("D2"); 593 if (D1_before != 3) e(6); 594 if (D2_before != 3) e(7); 595 if (D1_after != 2) e(8); 596 if (D2_after != 3) e(9); 597 if (x_link != 2) e(10); 598 if (y_link != 2) e(11); 599 if (access("D2/Y", 7) != 0) e(12); 600 if (rename("D2/Y", "D1/Z") != 0) e(13); 601 if (get_link("D1") != 3) e(14); 602 if (get_link("D2") != 2) e(15); 603 if (rmdir("D1/Z") != 0) e(16); 604 if (get_link("D1") != 2) e(17); 605 if (rmdir("D1") != 0) e(18); 606 if (rmdir("D2") != 0) e(19); 607 } 608 609 void test21o() 610 { 611 /* Test trying to remove . and .. */ 612 subtest = 14; 613 if (mkdir("D1", 0777) != 0) e(1); 614 if (chdir("D1") != 0) e(2); 615 if (rmdir(".") == 0) e(3); 616 if (rmdir("..") == 0) e(4); 617 if (mkdir("D2", 0777) != 0) e(5); 618 if (mkdir("D3", 0777) != 0) e(6); 619 if (mkdir("D4", 0777) != 0) e(7); 620 if (rmdir("D2/../D3/../D4") != 0) e(8); /* legal way to remove D4 */ 621 if (rmdir("D2/../D3/../D2/..") == 0) e(9); /* removing self is illegal */ 622 if (rmdir("D2/../D3/../D2/../..") == 0) e(10);/* removing parent is illegal*/ 623 if (rmdir("../D1/../D1/D3") != 0) e(11); /* legal way to remove D3 */ 624 if (rmdir("./D2/../D2") != 0) e(12); /* legal way to remove D2 */ 625 if (chdir("..") != 0) e(13); 626 if (rmdir("D1") != 0) e(14); 627 } 628 629 int get_link(name) 630 char *name; 631 { 632 struct stat statbuf; 633 634 if (stat(name, &statbuf) != 0) { 635 printf("Unable to stat %s\n", name); 636 errct++; 637 return(-1); 638 } 639 return(statbuf.st_nlink); 640 } 641 642