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