This source file includes following definitions.
- copyin
- copyout
- copyinstr1
- copyinstr2
- copyinstr3
- rwsbrk
- truncate1
- truncate2
- truncate3
- iputtest
- exitiputtest
- openiputtest
- opentest
- writetest
- writebig
- createtest
- dirtest
- exectest
- pipe1
- killstatus
- preempt
- exitwait
- reparent
- twochildren
- forkfork
- forkforkfork
- reparent2
- mem
- sharedfd
- fourfiles
- createdelete
- unlinkread
- linktest
- concreate
- linkunlink
- subdir
- bigwrite
- bigfile
- fourteen
- rmdot
- dirfile
- iref
- forktest
- sbrkbasic
- sbrkmuch
- kernmem
- MAXVAplus
- sbrkfail
- sbrkarg
- validatetest
- bsstest
- bigargtest
- fsfull
- argptest
- stacktest
- nowrite
- pgbug
- sbrkbugs
- sbrklast
- sbrk8000
- badarg
- lazy_alloc
- lazy_unmap
- lazy_copy
- bigdir
- manywrites
- badwrite
- execout
- diskfull
- outofinodes
- run
- runtests
- countfree
- drivetests
- main
1 #include "kernel/param.h"
2 #include "kernel/types.h"
3 #include "kernel/stat.h"
4 #include "user/user.h"
5 #include "kernel/fs.h"
6 #include "kernel/fcntl.h"
7 #include "kernel/syscall.h"
8 #include "kernel/memlayout.h"
9 #include "kernel/riscv.h"
10
11
12
13
14
15
16
17
18
19
20 #define BUFSZ ((MAXOPBLOCKS+2)*BSIZE)
21
22 char buf[BUFSZ];
23
24
25
26
27
28
29
30
31
32 void
33 copyin(char *s)
34 {
35 uint64 addrs[] = { 0x80000000LL, 0x3fffffe000, 0x3ffffff000, 0x4000000000,
36 0xffffffffffffffff };
37
38 for(int ai = 0; ai < sizeof(addrs)/sizeof(addrs[0]); ai++){
39 uint64 addr = addrs[ai];
40
41 int fd = open("copyin1", O_CREATE|O_WRONLY);
42 if(fd < 0){
43 printf("open(copyin1) failed\n");
44 exit(1);
45 }
46 int n = write(fd, (void*)addr, 8192);
47 if(n >= 0){
48 printf("write(fd, %p, 8192) returned %d, not -1\n", (void*)addr, n);
49 exit(1);
50 }
51 close(fd);
52 unlink("copyin1");
53
54 n = write(1, (char*)addr, 8192);
55 if(n > 0){
56 printf("write(1, %p, 8192) returned %d, not -1 or 0\n", (void*)addr, n);
57 exit(1);
58 }
59
60 int fds[2];
61 if(pipe(fds) < 0){
62 printf("pipe() failed\n");
63 exit(1);
64 }
65 n = write(fds[1], (char*)addr, 8192);
66 if(n > 0){
67 printf("write(pipe, %p, 8192) returned %d, not -1 or 0\n", (void*)addr, n);
68 exit(1);
69 }
70 close(fds[0]);
71 close(fds[1]);
72 }
73 }
74
75
76
77 void
78 copyout(char *s)
79 {
80 uint64 addrs[] = { 0LL, 0x80000000LL, 0x3fffffe000, 0x3ffffff000, 0x4000000000,
81 0xffffffffffffffff };
82
83 for(int ai = 0; ai < sizeof(addrs)/sizeof(addrs[0]); ai++){
84 uint64 addr = addrs[ai];
85
86 int fd = open("README", 0);
87 if(fd < 0){
88 printf("open(README) failed\n");
89 exit(1);
90 }
91 int n = read(fd, (void*)addr, 8192);
92 if(n > 0){
93 printf("read(fd, %p, 8192) returned %d, not -1 or 0\n", (void*)addr, n);
94 exit(1);
95 }
96 close(fd);
97
98 int fds[2];
99 if(pipe(fds) < 0){
100 printf("pipe() failed\n");
101 exit(1);
102 }
103 n = write(fds[1], "x", 1);
104 if(n != 1){
105 printf("pipe write failed\n");
106 exit(1);
107 }
108 n = read(fds[0], (void*)addr, 8192);
109 if(n > 0){
110 printf("read(pipe, %p, 8192) returned %d, not -1 or 0\n", (void*)addr, n);
111 exit(1);
112 }
113 close(fds[0]);
114 close(fds[1]);
115 }
116 }
117
118
119 void
120 copyinstr1(char *s)
121 {
122 uint64 addrs[] = { 0x80000000LL, 0x3fffffe000, 0x3ffffff000, 0x4000000000,
123 0xffffffffffffffff };
124
125 for(int ai = 0; ai < sizeof(addrs)/sizeof(addrs[0]); ai++){
126 uint64 addr = addrs[ai];
127
128 int fd = open((char *)addr, O_CREATE|O_WRONLY);
129 if(fd >= 0){
130 printf("open(%p) returned %d, not -1\n", (void*)addr, fd);
131 exit(1);
132 }
133 }
134 }
135
136
137
138
139 void
140 copyinstr2(char *s)
141 {
142 char b[MAXPATH+1];
143
144 for(int i = 0; i < MAXPATH; i++)
145 b[i] = 'x';
146 b[MAXPATH] = '\0';
147
148 int ret = unlink(b);
149 if(ret != -1){
150 printf("unlink(%s) returned %d, not -1\n", b, ret);
151 exit(1);
152 }
153
154 int fd = open(b, O_CREATE | O_WRONLY);
155 if(fd != -1){
156 printf("open(%s) returned %d, not -1\n", b, fd);
157 exit(1);
158 }
159
160 ret = link(b, b);
161 if(ret != -1){
162 printf("link(%s, %s) returned %d, not -1\n", b, b, ret);
163 exit(1);
164 }
165
166 char *args[] = { "xx", 0 };
167 ret = exec(b, args);
168 if(ret != -1){
169 printf("exec(%s) returned %d, not -1\n", b, fd);
170 exit(1);
171 }
172
173 int pid = fork();
174 if(pid < 0){
175 printf("fork failed\n");
176 exit(1);
177 }
178 if(pid == 0){
179 static char big[PGSIZE+1];
180 for(int i = 0; i < PGSIZE; i++)
181 big[i] = 'x';
182 big[PGSIZE] = '\0';
183 char *args2[] = { big, big, big, 0 };
184 ret = exec("echo", args2);
185 if(ret != -1){
186 printf("exec(echo, BIG) returned %d, not -1\n", fd);
187 exit(1);
188 }
189 exit(747);
190 }
191
192 int st = 0;
193 wait(&st);
194 if(st != 747){
195 printf("exec(echo, BIG) succeeded, should have failed\n");
196 exit(1);
197 }
198 }
199
200
201 void
202 copyinstr3(char *s)
203 {
204 sbrk(8192);
205 uint64 top = (uint64) sbrk(0);
206 if((top % PGSIZE) != 0){
207 sbrk(PGSIZE - (top % PGSIZE));
208 }
209 top = (uint64) sbrk(0);
210 if(top % PGSIZE){
211 printf("oops\n");
212 exit(1);
213 }
214
215 char *b = (char *) (top - 1);
216 *b = 'x';
217
218 int ret = unlink(b);
219 if(ret != -1){
220 printf("unlink(%s) returned %d, not -1\n", b, ret);
221 exit(1);
222 }
223
224 int fd = open(b, O_CREATE | O_WRONLY);
225 if(fd != -1){
226 printf("open(%s) returned %d, not -1\n", b, fd);
227 exit(1);
228 }
229
230 ret = link(b, b);
231 if(ret != -1){
232 printf("link(%s, %s) returned %d, not -1\n", b, b, ret);
233 exit(1);
234 }
235
236 char *args[] = { "xx", 0 };
237 ret = exec(b, args);
238 if(ret != -1){
239 printf("exec(%s) returned %d, not -1\n", b, fd);
240 exit(1);
241 }
242 }
243
244
245
246 void
247 rwsbrk(char *s)
248 {
249 int fd, n;
250
251 uint64 a = (uint64) sbrk(8192);
252
253 if(a == (uint64) SBRK_ERROR) {
254 printf("sbrk(rwsbrk) failed\n");
255 exit(1);
256 }
257
258 if (sbrk(-8192) == SBRK_ERROR) {
259 printf("sbrk(rwsbrk) shrink failed\n");
260 exit(1);
261 }
262
263 fd = open("rwsbrk", O_CREATE|O_WRONLY);
264 if(fd < 0){
265 printf("open(rwsbrk) failed\n");
266 exit(1);
267 }
268 n = write(fd, (void*)(a+PGSIZE), 1024);
269 if(n >= 0){
270 printf("write(fd, %p, 1024) returned %d, not -1\n", (void*)a+PGSIZE, n);
271 exit(1);
272 }
273 close(fd);
274 unlink("rwsbrk");
275
276 fd = open("README", O_RDONLY);
277 if(fd < 0){
278 printf("open(README) failed\n");
279 exit(1);
280 }
281 n = read(fd, (void*)(a+PGSIZE), 10);
282 if(n >= 0){
283 printf("read(fd, %p, 10) returned %d, not -1\n", (void*)a+PGSIZE, n);
284 exit(1);
285 }
286 close(fd);
287
288 exit(0);
289 }
290
291
292 void
293 truncate1(char *s)
294 {
295 char buf[32];
296
297 unlink("truncfile");
298 int fd1 = open("truncfile", O_CREATE|O_WRONLY|O_TRUNC);
299 write(fd1, "abcd", 4);
300 close(fd1);
301
302 int fd2 = open("truncfile", O_RDONLY);
303 int n = read(fd2, buf, sizeof(buf));
304 if(n != 4){
305 printf("%s: read %d bytes, wanted 4\n", s, n);
306 exit(1);
307 }
308
309 fd1 = open("truncfile", O_WRONLY|O_TRUNC);
310
311 int fd3 = open("truncfile", O_RDONLY);
312 n = read(fd3, buf, sizeof(buf));
313 if(n != 0){
314 printf("aaa fd3=%d\n", fd3);
315 printf("%s: read %d bytes, wanted 0\n", s, n);
316 exit(1);
317 }
318
319 n = read(fd2, buf, sizeof(buf));
320 if(n != 0){
321 printf("bbb fd2=%d\n", fd2);
322 printf("%s: read %d bytes, wanted 0\n", s, n);
323 exit(1);
324 }
325
326 write(fd1, "abcdef", 6);
327
328 n = read(fd3, buf, sizeof(buf));
329 if(n != 6){
330 printf("%s: read %d bytes, wanted 6\n", s, n);
331 exit(1);
332 }
333
334 n = read(fd2, buf, sizeof(buf));
335 if(n != 2){
336 printf("%s: read %d bytes, wanted 2\n", s, n);
337 exit(1);
338 }
339
340 unlink("truncfile");
341
342 close(fd1);
343 close(fd2);
344 close(fd3);
345 }
346
347
348
349
350
351 void
352 truncate2(char *s)
353 {
354 unlink("truncfile");
355
356 int fd1 = open("truncfile", O_CREATE|O_TRUNC|O_WRONLY);
357 write(fd1, "abcd", 4);
358
359 int fd2 = open("truncfile", O_TRUNC|O_WRONLY);
360
361 int n = write(fd1, "x", 1);
362 if(n != -1){
363 printf("%s: write returned %d, expected -1\n", s, n);
364 exit(1);
365 }
366
367 unlink("truncfile");
368 close(fd1);
369 close(fd2);
370 }
371
372 void
373 truncate3(char *s)
374 {
375 int pid, xstatus;
376
377 close(open("truncfile", O_CREATE|O_TRUNC|O_WRONLY));
378
379 pid = fork();
380 if(pid < 0){
381 printf("%s: fork failed\n", s);
382 exit(1);
383 }
384
385 if(pid == 0){
386 for(int i = 0; i < 100; i++){
387 char buf[32];
388 int fd = open("truncfile", O_WRONLY);
389 if(fd < 0){
390 printf("%s: open failed\n", s);
391 exit(1);
392 }
393 int n = write(fd, "1234567890", 10);
394 if(n != 10){
395 printf("%s: write got %d, expected 10\n", s, n);
396 exit(1);
397 }
398 close(fd);
399 fd = open("truncfile", O_RDONLY);
400 read(fd, buf, sizeof(buf));
401 close(fd);
402 }
403 exit(0);
404 }
405
406 for(int i = 0; i < 150; i++){
407 int fd = open("truncfile", O_CREATE|O_WRONLY|O_TRUNC);
408 if(fd < 0){
409 printf("%s: open failed\n", s);
410 exit(1);
411 }
412 int n = write(fd, "xxx", 3);
413 if(n != 3){
414 printf("%s: write got %d, expected 3\n", s, n);
415 exit(1);
416 }
417 close(fd);
418 }
419
420 wait(&xstatus);
421 unlink("truncfile");
422 exit(xstatus);
423 }
424
425
426
427 void
428 iputtest(char *s)
429 {
430 if(mkdir("iputdir") < 0){
431 printf("%s: mkdir failed\n", s);
432 exit(1);
433 }
434 if(chdir("iputdir") < 0){
435 printf("%s: chdir iputdir failed\n", s);
436 exit(1);
437 }
438 if(unlink("../iputdir") < 0){
439 printf("%s: unlink ../iputdir failed\n", s);
440 exit(1);
441 }
442 if(chdir("/") < 0){
443 printf("%s: chdir / failed\n", s);
444 exit(1);
445 }
446 }
447
448
449 void
450 exitiputtest(char *s)
451 {
452 int pid, xstatus;
453
454 pid = fork();
455 if(pid < 0){
456 printf("%s: fork failed\n", s);
457 exit(1);
458 }
459 if(pid == 0){
460 if(mkdir("iputdir") < 0){
461 printf("%s: mkdir failed\n", s);
462 exit(1);
463 }
464 if(chdir("iputdir") < 0){
465 printf("%s: child chdir failed\n", s);
466 exit(1);
467 }
468 if(unlink("../iputdir") < 0){
469 printf("%s: unlink ../iputdir failed\n", s);
470 exit(1);
471 }
472 exit(0);
473 }
474 wait(&xstatus);
475 exit(xstatus);
476 }
477
478
479
480
481
482
483
484
485
486
487
488
489 void
490 openiputtest(char *s)
491 {
492 int pid, xstatus;
493
494 if(mkdir("oidir") < 0){
495 printf("%s: mkdir oidir failed\n", s);
496 exit(1);
497 }
498 pid = fork();
499 if(pid < 0){
500 printf("%s: fork failed\n", s);
501 exit(1);
502 }
503 if(pid == 0){
504 int fd = open("oidir", O_RDWR);
505 if(fd >= 0){
506 printf("%s: open directory for write succeeded\n", s);
507 exit(1);
508 }
509 exit(0);
510 }
511 pause(1);
512 if(unlink("oidir") != 0){
513 printf("%s: unlink failed\n", s);
514 exit(1);
515 }
516 wait(&xstatus);
517 exit(xstatus);
518 }
519
520
521
522 void
523 opentest(char *s)
524 {
525 int fd;
526
527 fd = open("echo", 0);
528 if(fd < 0){
529 printf("%s: open echo failed!\n", s);
530 exit(1);
531 }
532 close(fd);
533 fd = open("doesnotexist", 0);
534 if(fd >= 0){
535 printf("%s: open doesnotexist succeeded!\n", s);
536 exit(1);
537 }
538 }
539
540 void
541 writetest(char *s)
542 {
543 int fd;
544 int i;
545 enum { N=100, SZ=10 };
546
547 fd = open("small", O_CREATE|O_RDWR);
548 if(fd < 0){
549 printf("%s: error: creat small failed!\n", s);
550 exit(1);
551 }
552 for(i = 0; i < N; i++){
553 if(write(fd, "aaaaaaaaaa", SZ) != SZ){
554 printf("%s: error: write aa %d new file failed\n", s, i);
555 exit(1);
556 }
557 if(write(fd, "bbbbbbbbbb", SZ) != SZ){
558 printf("%s: error: write bb %d new file failed\n", s, i);
559 exit(1);
560 }
561 }
562 close(fd);
563 fd = open("small", O_RDONLY);
564 if(fd < 0){
565 printf("%s: error: open small failed!\n", s);
566 exit(1);
567 }
568 i = read(fd, buf, N*SZ*2);
569 if(i != N*SZ*2){
570 printf("%s: read failed\n", s);
571 exit(1);
572 }
573 close(fd);
574
575 if(unlink("small") < 0){
576 printf("%s: unlink small failed\n", s);
577 exit(1);
578 }
579 }
580
581 void
582 writebig(char *s)
583 {
584 int i, fd, n;
585
586 fd = open("big", O_CREATE|O_RDWR);
587 if(fd < 0){
588 printf("%s: error: creat big failed!\n", s);
589 exit(1);
590 }
591
592 for(i = 0; i < MAXFILE; i++){
593 ((int*)buf)[0] = i;
594 if(write(fd, buf, BSIZE) != BSIZE){
595 printf("%s: error: write big file failed i=%d\n", s, i);
596 exit(1);
597 }
598 }
599
600 close(fd);
601
602 fd = open("big", O_RDONLY);
603 if(fd < 0){
604 printf("%s: error: open big failed!\n", s);
605 exit(1);
606 }
607
608 n = 0;
609 for(;;){
610 i = read(fd, buf, BSIZE);
611 if(i == 0){
612 if(n != MAXFILE){
613 printf("%s: read only %d blocks from big", s, n);
614 exit(1);
615 }
616 break;
617 } else if(i != BSIZE){
618 printf("%s: read failed %d\n", s, i);
619 exit(1);
620 }
621 if(((int*)buf)[0] != n){
622 printf("%s: read content of block %d is %d\n", s,
623 n, ((int*)buf)[0]);
624 exit(1);
625 }
626 n++;
627 }
628 close(fd);
629 if(unlink("big") < 0){
630 printf("%s: unlink big failed\n", s);
631 exit(1);
632 }
633 }
634
635
636 void
637 createtest(char *s)
638 {
639 int i, fd;
640 enum { N=52 };
641
642 char name[3];
643 name[0] = 'a';
644 name[2] = '\0';
645 for(i = 0; i < N; i++){
646 name[1] = '0' + i;
647 fd = open(name, O_CREATE|O_RDWR);
648 close(fd);
649 }
650 name[0] = 'a';
651 name[2] = '\0';
652 for(i = 0; i < N; i++){
653 name[1] = '0' + i;
654 unlink(name);
655 }
656 }
657
658 void dirtest(char *s)
659 {
660 if(mkdir("dir0") < 0){
661 printf("%s: mkdir failed\n", s);
662 exit(1);
663 }
664
665 if(chdir("dir0") < 0){
666 printf("%s: chdir dir0 failed\n", s);
667 exit(1);
668 }
669
670 if(chdir("..") < 0){
671 printf("%s: chdir .. failed\n", s);
672 exit(1);
673 }
674
675 if(unlink("dir0") < 0){
676 printf("%s: unlink dir0 failed\n", s);
677 exit(1);
678 }
679 }
680
681 void
682 exectest(char *s)
683 {
684 int fd, xstatus, pid;
685 char *echoargv[] = { "echo", "OK", 0 };
686 char buf[3];
687
688 unlink("echo-ok");
689 pid = fork();
690 if(pid < 0) {
691 printf("%s: fork failed\n", s);
692 exit(1);
693 }
694 if(pid == 0) {
695 close(1);
696 fd = open("echo-ok", O_CREATE|O_WRONLY);
697 if(fd < 0) {
698 printf("%s: create failed\n", s);
699 exit(1);
700 }
701 if(fd != 1) {
702 printf("%s: wrong fd\n", s);
703 exit(1);
704 }
705 if(exec("echo", echoargv) < 0){
706 printf("%s: exec echo failed\n", s);
707 exit(1);
708 }
709
710 }
711 if (wait(&xstatus) != pid) {
712 printf("%s: wait failed!\n", s);
713 }
714 if(xstatus != 0)
715 exit(xstatus);
716
717 fd = open("echo-ok", O_RDONLY);
718 if(fd < 0) {
719 printf("%s: open failed\n", s);
720 exit(1);
721 }
722 if (read(fd, buf, 2) != 2) {
723 printf("%s: read failed\n", s);
724 exit(1);
725 }
726 unlink("echo-ok");
727 if(buf[0] == 'O' && buf[1] == 'K')
728 exit(0);
729 else {
730 printf("%s: wrong output\n", s);
731 exit(1);
732 }
733
734 }
735
736
737
738 void
739 pipe1(char *s)
740 {
741 int fds[2], pid, xstatus;
742 int seq, i, n, cc, total;
743 enum { N=5, SZ=1033 };
744
745 if(pipe(fds) != 0){
746 printf("%s: pipe() failed\n", s);
747 exit(1);
748 }
749 pid = fork();
750 seq = 0;
751 if(pid == 0){
752 close(fds[0]);
753 for(n = 0; n < N; n++){
754 for(i = 0; i < SZ; i++)
755 buf[i] = seq++;
756 if(write(fds[1], buf, SZ) != SZ){
757 printf("%s: pipe1 oops 1\n", s);
758 exit(1);
759 }
760 }
761 exit(0);
762 } else if(pid > 0){
763 close(fds[1]);
764 total = 0;
765 cc = 1;
766 while((n = read(fds[0], buf, cc)) > 0){
767 for(i = 0; i < n; i++){
768 if((buf[i] & 0xff) != (seq++ & 0xff)){
769 printf("%s: pipe1 oops 2\n", s);
770 return;
771 }
772 }
773 total += n;
774 cc = cc * 2;
775 if(cc > sizeof(buf))
776 cc = sizeof(buf);
777 }
778 if(total != N * SZ){
779 printf("%s: pipe1 oops 3 total %d\n", s, total);
780 exit(1);
781 }
782 close(fds[0]);
783 wait(&xstatus);
784 exit(xstatus);
785 } else {
786 printf("%s: fork() failed\n", s);
787 exit(1);
788 }
789 }
790
791
792
793 void
794 killstatus(char *s)
795 {
796 int xst;
797
798 for(int i = 0; i < 100; i++){
799 int pid1 = fork();
800 if(pid1 < 0){
801 printf("%s: fork failed\n", s);
802 exit(1);
803 }
804 if(pid1 == 0){
805 while(1) {
806 getpid();
807 }
808 exit(0);
809 }
810 pause(1);
811 kill(pid1);
812 wait(&xst);
813 if(xst != -1) {
814 printf("%s: status should be -1\n", s);
815 exit(1);
816 }
817 }
818 exit(0);
819 }
820
821
822 void
823 preempt(char *s)
824 {
825 int pid1, pid2, pid3;
826 int pfds[2];
827
828 pid1 = fork();
829 if(pid1 < 0) {
830 printf("%s: fork failed", s);
831 exit(1);
832 }
833 if(pid1 == 0)
834 for(;;)
835 ;
836
837 pid2 = fork();
838 if(pid2 < 0) {
839 printf("%s: fork failed\n", s);
840 exit(1);
841 }
842 if(pid2 == 0)
843 for(;;)
844 ;
845
846 pipe(pfds);
847 pid3 = fork();
848 if(pid3 < 0) {
849 printf("%s: fork failed\n", s);
850 exit(1);
851 }
852 if(pid3 == 0){
853 close(pfds[0]);
854 if(write(pfds[1], "x", 1) != 1)
855 printf("%s: preempt write error", s);
856 close(pfds[1]);
857 for(;;)
858 ;
859 }
860
861 close(pfds[1]);
862 if(read(pfds[0], buf, sizeof(buf)) != 1){
863 printf("%s: preempt read error", s);
864 return;
865 }
866 close(pfds[0]);
867 printf("kill... ");
868 kill(pid1);
869 kill(pid2);
870 kill(pid3);
871 printf("wait... ");
872 wait(0);
873 wait(0);
874 wait(0);
875 }
876
877
878 void
879 exitwait(char *s)
880 {
881 int i, pid;
882
883 for(i = 0; i < 100; i++){
884 pid = fork();
885 if(pid < 0){
886 printf("%s: fork failed\n", s);
887 exit(1);
888 }
889 if(pid){
890 int xstate;
891 if(wait(&xstate) != pid){
892 printf("%s: wait wrong pid\n", s);
893 exit(1);
894 }
895 if(i != xstate) {
896 printf("%s: wait wrong exit status\n", s);
897 exit(1);
898 }
899 } else {
900 exit(i);
901 }
902 }
903 }
904
905
906
907
908 void
909 reparent(char *s)
910 {
911 int master_pid = getpid();
912 for(int i = 0; i < 200; i++){
913 int pid = fork();
914 if(pid < 0){
915 printf("%s: fork failed\n", s);
916 exit(1);
917 }
918 if(pid){
919 if(wait(0) != pid){
920 printf("%s: wait wrong pid\n", s);
921 exit(1);
922 }
923 } else {
924 int pid2 = fork();
925 if(pid2 < 0){
926 kill(master_pid);
927 exit(1);
928 }
929 exit(0);
930 }
931 }
932 exit(0);
933 }
934
935
936 void
937 twochildren(char *s)
938 {
939 for(int i = 0; i < 1000; i++){
940 int pid1 = fork();
941 if(pid1 < 0){
942 printf("%s: fork failed\n", s);
943 exit(1);
944 }
945 if(pid1 == 0){
946 exit(0);
947 } else {
948 int pid2 = fork();
949 if(pid2 < 0){
950 printf("%s: fork failed\n", s);
951 exit(1);
952 }
953 if(pid2 == 0){
954 exit(0);
955 } else {
956 wait(0);
957 wait(0);
958 }
959 }
960 }
961 }
962
963
964 void
965 forkfork(char *s)
966 {
967 enum { N=2 };
968
969 for(int i = 0; i < N; i++){
970 int pid = fork();
971 if(pid < 0){
972 printf("%s: fork failed", s);
973 exit(1);
974 }
975 if(pid == 0){
976 for(int j = 0; j < 200; j++){
977 int pid1 = fork();
978 if(pid1 < 0){
979 exit(1);
980 }
981 if(pid1 == 0){
982 exit(0);
983 }
984 wait(0);
985 }
986 exit(0);
987 }
988 }
989
990 int xstatus;
991 for(int i = 0; i < N; i++){
992 wait(&xstatus);
993 if(xstatus != 0) {
994 printf("%s: fork in child failed", s);
995 exit(1);
996 }
997 }
998 }
999
1000 void
1001 forkforkfork(char *s)
1002 {
1003 unlink("stopforking");
1004
1005 int pid = fork();
1006 if(pid < 0){
1007 printf("%s: fork failed", s);
1008 exit(1);
1009 }
1010 if(pid == 0){
1011 while(1){
1012 int fd = open("stopforking", 0);
1013 if(fd >= 0){
1014 exit(0);
1015 }
1016 if(fork() < 0){
1017 close(open("stopforking", O_CREATE|O_RDWR));
1018 }
1019 }
1020
1021 exit(0);
1022 }
1023
1024 pause(20);
1025 close(open("stopforking", O_CREATE|O_RDWR));
1026 wait(0);
1027 pause(10);
1028 }
1029
1030
1031
1032
1033
1034
1035 void
1036 reparent2(char *s)
1037 {
1038 for(int i = 0; i < 800; i++){
1039 int pid1 = fork();
1040 if(pid1 < 0){
1041 printf("fork failed\n");
1042 exit(1);
1043 }
1044 if(pid1 == 0){
1045 fork();
1046 fork();
1047 exit(0);
1048 }
1049 wait(0);
1050 }
1051
1052 exit(0);
1053 }
1054
1055
1056 void
1057 mem(char *s)
1058 {
1059 void *m1, *m2;
1060 int pid;
1061
1062 if((pid = fork()) == 0){
1063 m1 = 0;
1064 while((m2 = malloc(10001)) != 0){
1065 *(char**)m2 = m1;
1066 m1 = m2;
1067 }
1068 while(m1){
1069 m2 = *(char**)m1;
1070 free(m1);
1071 m1 = m2;
1072 }
1073 m1 = malloc(1024*20);
1074 if(m1 == 0){
1075 printf("%s: couldn't allocate mem?!!\n", s);
1076 exit(1);
1077 }
1078 free(m1);
1079 exit(0);
1080 } else {
1081 int xstatus;
1082 wait(&xstatus);
1083 if(xstatus == -1){
1084
1085
1086 exit(0);
1087 }
1088 exit(xstatus);
1089 }
1090 }
1091
1092
1093
1094
1095
1096 void
1097 sharedfd(char *s)
1098 {
1099 int fd, pid, i, n, nc, np;
1100 enum { N = 1000, SZ=10};
1101 char buf[SZ];
1102
1103 unlink("sharedfd");
1104 fd = open("sharedfd", O_CREATE|O_RDWR);
1105 if(fd < 0){
1106 printf("%s: cannot open sharedfd for writing", s);
1107 exit(1);
1108 }
1109 pid = fork();
1110 memset(buf, pid==0?'c':'p', sizeof(buf));
1111 for(i = 0; i < N; i++){
1112 if(write(fd, buf, sizeof(buf)) != sizeof(buf)){
1113 printf("%s: write sharedfd failed\n", s);
1114 exit(1);
1115 }
1116 }
1117 if(pid == 0) {
1118 exit(0);
1119 } else {
1120 int xstatus;
1121 wait(&xstatus);
1122 if(xstatus != 0)
1123 exit(xstatus);
1124 }
1125
1126 close(fd);
1127 fd = open("sharedfd", 0);
1128 if(fd < 0){
1129 printf("%s: cannot open sharedfd for reading\n", s);
1130 exit(1);
1131 }
1132 nc = np = 0;
1133 while((n = read(fd, buf, sizeof(buf))) > 0){
1134 for(i = 0; i < sizeof(buf); i++){
1135 if(buf[i] == 'c')
1136 nc++;
1137 if(buf[i] == 'p')
1138 np++;
1139 }
1140 }
1141 close(fd);
1142 unlink("sharedfd");
1143 if(nc == N*SZ && np == N*SZ){
1144 exit(0);
1145 } else {
1146 printf("%s: nc/np test fails\n", s);
1147 exit(1);
1148 }
1149 }
1150
1151
1152
1153 void
1154 fourfiles(char *s)
1155 {
1156 int fd, pid, i, j, n, total, pi;
1157 char *names[] = { "f0", "f1", "f2", "f3" };
1158 char *fname;
1159 enum { N=12, NCHILD=4, SZ=500 };
1160
1161 for(pi = 0; pi < NCHILD; pi++){
1162 fname = names[pi];
1163 unlink(fname);
1164
1165 pid = fork();
1166 if(pid < 0){
1167 printf("%s: fork failed\n", s);
1168 exit(1);
1169 }
1170
1171 if(pid == 0){
1172 fd = open(fname, O_CREATE | O_RDWR);
1173 if(fd < 0){
1174 printf("%s: create failed\n", s);
1175 exit(1);
1176 }
1177
1178 memset(buf, '0'+pi, SZ);
1179 for(i = 0; i < N; i++){
1180 if((n = write(fd, buf, SZ)) != SZ){
1181 printf("write failed %d\n", n);
1182 exit(1);
1183 }
1184 }
1185 exit(0);
1186 }
1187 }
1188
1189 int xstatus;
1190 for(pi = 0; pi < NCHILD; pi++){
1191 wait(&xstatus);
1192 if(xstatus != 0)
1193 exit(xstatus);
1194 }
1195
1196 for(i = 0; i < NCHILD; i++){
1197 fname = names[i];
1198 fd = open(fname, 0);
1199 total = 0;
1200 while((n = read(fd, buf, sizeof(buf))) > 0){
1201 for(j = 0; j < n; j++){
1202 if(buf[j] != '0'+i){
1203 printf("%s: wrong char\n", s);
1204 exit(1);
1205 }
1206 }
1207 total += n;
1208 }
1209 close(fd);
1210 if(total != N*SZ){
1211 printf("wrong length %d\n", total);
1212 exit(1);
1213 }
1214 unlink(fname);
1215 }
1216 }
1217
1218
1219 void
1220 createdelete(char *s)
1221 {
1222 enum { N = 20, NCHILD=4 };
1223 int pid, i, fd, pi;
1224 char name[32];
1225
1226 for(pi = 0; pi < NCHILD; pi++){
1227 pid = fork();
1228 if(pid < 0){
1229 printf("%s: fork failed\n", s);
1230 exit(1);
1231 }
1232
1233 if(pid == 0){
1234 name[0] = 'p' + pi;
1235 name[2] = '\0';
1236 for(i = 0; i < N; i++){
1237 name[1] = '0' + i;
1238 fd = open(name, O_CREATE | O_RDWR);
1239 if(fd < 0){
1240 printf("%s: create failed\n", s);
1241 exit(1);
1242 }
1243 close(fd);
1244 if(i > 0 && (i % 2 ) == 0){
1245 name[1] = '0' + (i / 2);
1246 if(unlink(name) < 0){
1247 printf("%s: unlink failed\n", s);
1248 exit(1);
1249 }
1250 }
1251 }
1252 exit(0);
1253 }
1254 }
1255
1256 int xstatus;
1257 for(pi = 0; pi < NCHILD; pi++){
1258 wait(&xstatus);
1259 if(xstatus != 0)
1260 exit(1);
1261 }
1262
1263 name[0] = name[1] = name[2] = 0;
1264 for(i = 0; i < N; i++){
1265 for(pi = 0; pi < NCHILD; pi++){
1266 name[0] = 'p' + pi;
1267 name[1] = '0' + i;
1268 fd = open(name, 0);
1269 if((i == 0 || i >= N/2) && fd < 0){
1270 printf("%s: oops createdelete %s didn't exist\n", s, name);
1271 exit(1);
1272 } else if((i >= 1 && i < N/2) && fd >= 0){
1273 printf("%s: oops createdelete %s did exist\n", s, name);
1274 exit(1);
1275 }
1276 if(fd >= 0)
1277 close(fd);
1278 }
1279 }
1280
1281 for(i = 0; i < N; i++){
1282 for(pi = 0; pi < NCHILD; pi++){
1283 name[0] = 'p' + pi;
1284 name[1] = '0' + i;
1285 unlink(name);
1286 }
1287 }
1288 }
1289
1290
1291 void
1292 unlinkread(char *s)
1293 {
1294 enum { SZ = 5 };
1295 int fd, fd1;
1296
1297 fd = open("unlinkread", O_CREATE | O_RDWR);
1298 if(fd < 0){
1299 printf("%s: create unlinkread failed\n", s);
1300 exit(1);
1301 }
1302 write(fd, "hello", SZ);
1303 close(fd);
1304
1305 fd = open("unlinkread", O_RDWR);
1306 if(fd < 0){
1307 printf("%s: open unlinkread failed\n", s);
1308 exit(1);
1309 }
1310 if(unlink("unlinkread") != 0){
1311 printf("%s: unlink unlinkread failed\n", s);
1312 exit(1);
1313 }
1314
1315 fd1 = open("unlinkread", O_CREATE | O_RDWR);
1316 write(fd1, "yyy", 3);
1317 close(fd1);
1318
1319 if(read(fd, buf, sizeof(buf)) != SZ){
1320 printf("%s: unlinkread read failed", s);
1321 exit(1);
1322 }
1323 if(buf[0] != 'h'){
1324 printf("%s: unlinkread wrong data\n", s);
1325 exit(1);
1326 }
1327 if(write(fd, buf, 10) != 10){
1328 printf("%s: unlinkread write failed\n", s);
1329 exit(1);
1330 }
1331 close(fd);
1332 unlink("unlinkread");
1333 }
1334
1335 void
1336 linktest(char *s)
1337 {
1338 enum { SZ = 5 };
1339 int fd;
1340
1341 unlink("lf1");
1342 unlink("lf2");
1343
1344 fd = open("lf1", O_CREATE|O_RDWR);
1345 if(fd < 0){
1346 printf("%s: create lf1 failed\n", s);
1347 exit(1);
1348 }
1349 if(write(fd, "hello", SZ) != SZ){
1350 printf("%s: write lf1 failed\n", s);
1351 exit(1);
1352 }
1353 close(fd);
1354
1355 if(link("lf1", "lf2") < 0){
1356 printf("%s: link lf1 lf2 failed\n", s);
1357 exit(1);
1358 }
1359 unlink("lf1");
1360
1361 if(open("lf1", 0) >= 0){
1362 printf("%s: unlinked lf1 but it is still there!\n", s);
1363 exit(1);
1364 }
1365
1366 fd = open("lf2", 0);
1367 if(fd < 0){
1368 printf("%s: open lf2 failed\n", s);
1369 exit(1);
1370 }
1371 if(read(fd, buf, sizeof(buf)) != SZ){
1372 printf("%s: read lf2 failed\n", s);
1373 exit(1);
1374 }
1375 close(fd);
1376
1377 if(link("lf2", "lf2") >= 0){
1378 printf("%s: link lf2 lf2 succeeded! oops\n", s);
1379 exit(1);
1380 }
1381
1382 unlink("lf2");
1383 if(link("lf2", "lf1") >= 0){
1384 printf("%s: link non-existent succeeded! oops\n", s);
1385 exit(1);
1386 }
1387
1388 if(link(".", "lf1") >= 0){
1389 printf("%s: link . lf1 succeeded! oops\n", s);
1390 exit(1);
1391 }
1392 }
1393
1394
1395 void
1396 concreate(char *s)
1397 {
1398 enum { N = 40 };
1399 char file[3];
1400 int i, pid, n, fd;
1401 char fa[N];
1402 struct {
1403 ushort inum;
1404 char name[DIRSIZ];
1405 } de;
1406
1407 file[0] = 'C';
1408 file[2] = '\0';
1409 for(i = 0; i < N; i++){
1410 file[1] = '0' + i;
1411 unlink(file);
1412 pid = fork();
1413 if(pid && (i % 3) == 1){
1414 link("C0", file);
1415 } else if(pid == 0 && (i % 5) == 1){
1416 link("C0", file);
1417 } else {
1418 fd = open(file, O_CREATE | O_RDWR);
1419 if(fd < 0){
1420 printf("concreate create %s failed\n", file);
1421 exit(1);
1422 }
1423 close(fd);
1424 }
1425 if(pid == 0) {
1426 exit(0);
1427 } else {
1428 int xstatus;
1429 wait(&xstatus);
1430 if(xstatus != 0)
1431 exit(1);
1432 }
1433 }
1434
1435 memset(fa, 0, sizeof(fa));
1436 fd = open(".", 0);
1437 n = 0;
1438 while(read(fd, &de, sizeof(de)) > 0){
1439 if(de.inum == 0)
1440 continue;
1441 if(de.name[0] == 'C' && de.name[2] == '\0'){
1442 i = de.name[1] - '0';
1443 if(i < 0 || i >= sizeof(fa)){
1444 printf("%s: concreate weird file %s\n", s, de.name);
1445 exit(1);
1446 }
1447 if(fa[i]){
1448 printf("%s: concreate duplicate file %s\n", s, de.name);
1449 exit(1);
1450 }
1451 fa[i] = 1;
1452 n++;
1453 }
1454 }
1455 close(fd);
1456
1457 if(n != N){
1458 printf("%s: concreate not enough files in directory listing\n", s);
1459 exit(1);
1460 }
1461
1462 for(i = 0; i < N; i++){
1463 file[1] = '0' + i;
1464 pid = fork();
1465 if(pid < 0){
1466 printf("%s: fork failed\n", s);
1467 exit(1);
1468 }
1469 if(((i % 3) == 0 && pid == 0) ||
1470 ((i % 3) == 1 && pid != 0)){
1471 close(open(file, 0));
1472 close(open(file, 0));
1473 close(open(file, 0));
1474 close(open(file, 0));
1475 close(open(file, 0));
1476 close(open(file, 0));
1477 } else {
1478 unlink(file);
1479 unlink(file);
1480 unlink(file);
1481 unlink(file);
1482 unlink(file);
1483 unlink(file);
1484 }
1485 if(pid == 0)
1486 exit(0);
1487 else
1488 wait(0);
1489 }
1490 }
1491
1492
1493
1494 void
1495 linkunlink(char *s)
1496 {
1497 int pid, i;
1498
1499 unlink("x");
1500 pid = fork();
1501 if(pid < 0){
1502 printf("%s: fork failed\n", s);
1503 exit(1);
1504 }
1505
1506 unsigned int x = (pid ? 1 : 97);
1507 for(i = 0; i < 100; i++){
1508 x = x * 1103515245 + 12345;
1509 if((x % 3) == 0){
1510 close(open("x", O_RDWR | O_CREATE));
1511 } else if((x % 3) == 1){
1512 link("cat", "x");
1513 } else {
1514 unlink("x");
1515 }
1516 }
1517
1518 if(pid)
1519 wait(0);
1520 else
1521 exit(0);
1522 }
1523
1524
1525 void
1526 subdir(char *s)
1527 {
1528 int fd, cc;
1529
1530 unlink("ff");
1531 if(mkdir("dd") != 0){
1532 printf("%s: mkdir dd failed\n", s);
1533 exit(1);
1534 }
1535
1536 fd = open("dd/ff", O_CREATE | O_RDWR);
1537 if(fd < 0){
1538 printf("%s: create dd/ff failed\n", s);
1539 exit(1);
1540 }
1541 write(fd, "ff", 2);
1542 close(fd);
1543
1544 if(unlink("dd") >= 0){
1545 printf("%s: unlink dd (non-empty dir) succeeded!\n", s);
1546 exit(1);
1547 }
1548
1549 if(mkdir("/dd/dd") != 0){
1550 printf("%s: subdir mkdir dd/dd failed\n", s);
1551 exit(1);
1552 }
1553
1554 fd = open("dd/dd/ff", O_CREATE | O_RDWR);
1555 if(fd < 0){
1556 printf("%s: create dd/dd/ff failed\n", s);
1557 exit(1);
1558 }
1559 write(fd, "FF", 2);
1560 close(fd);
1561
1562 fd = open("dd/dd/../ff", 0);
1563 if(fd < 0){
1564 printf("%s: open dd/dd/../ff failed\n", s);
1565 exit(1);
1566 }
1567 cc = read(fd, buf, sizeof(buf));
1568 if(cc != 2 || buf[0] != 'f'){
1569 printf("%s: dd/dd/../ff wrong content\n", s);
1570 exit(1);
1571 }
1572 close(fd);
1573
1574 if(link("dd/dd/ff", "dd/dd/ffff") != 0){
1575 printf("%s: link dd/dd/ff dd/dd/ffff failed\n", s);
1576 exit(1);
1577 }
1578
1579 if(unlink("dd/dd/ff") != 0){
1580 printf("%s: unlink dd/dd/ff failed\n", s);
1581 exit(1);
1582 }
1583 if(open("dd/dd/ff", O_RDONLY) >= 0){
1584 printf("%s: open (unlinked) dd/dd/ff succeeded\n", s);
1585 exit(1);
1586 }
1587
1588 if(chdir("dd") != 0){
1589 printf("%s: chdir dd failed\n", s);
1590 exit(1);
1591 }
1592 if(chdir("dd/../../dd") != 0){
1593 printf("%s: chdir dd/../../dd failed\n", s);
1594 exit(1);
1595 }
1596 if(chdir("dd/../../../dd") != 0){
1597 printf("%s: chdir dd/../../../dd failed\n", s);
1598 exit(1);
1599 }
1600 if(chdir("./..") != 0){
1601 printf("%s: chdir ./.. failed\n", s);
1602 exit(1);
1603 }
1604
1605 fd = open("dd/dd/ffff", 0);
1606 if(fd < 0){
1607 printf("%s: open dd/dd/ffff failed\n", s);
1608 exit(1);
1609 }
1610 if(read(fd, buf, sizeof(buf)) != 2){
1611 printf("%s: read dd/dd/ffff wrong len\n", s);
1612 exit(1);
1613 }
1614 close(fd);
1615
1616 if(open("dd/dd/ff", O_RDONLY) >= 0){
1617 printf("%s: open (unlinked) dd/dd/ff succeeded!\n", s);
1618 exit(1);
1619 }
1620
1621 if(open("dd/ff/ff", O_CREATE|O_RDWR) >= 0){
1622 printf("%s: create dd/ff/ff succeeded!\n", s);
1623 exit(1);
1624 }
1625 if(open("dd/xx/ff", O_CREATE|O_RDWR) >= 0){
1626 printf("%s: create dd/xx/ff succeeded!\n", s);
1627 exit(1);
1628 }
1629 if(open("dd", O_CREATE) >= 0){
1630 printf("%s: create dd succeeded!\n", s);
1631 exit(1);
1632 }
1633 if(open("dd", O_RDWR) >= 0){
1634 printf("%s: open dd rdwr succeeded!\n", s);
1635 exit(1);
1636 }
1637 if(open("dd", O_WRONLY) >= 0){
1638 printf("%s: open dd wronly succeeded!\n", s);
1639 exit(1);
1640 }
1641 if(link("dd/ff/ff", "dd/dd/xx") == 0){
1642 printf("%s: link dd/ff/ff dd/dd/xx succeeded!\n", s);
1643 exit(1);
1644 }
1645 if(link("dd/xx/ff", "dd/dd/xx") == 0){
1646 printf("%s: link dd/xx/ff dd/dd/xx succeeded!\n", s);
1647 exit(1);
1648 }
1649 if(link("dd/ff", "dd/dd/ffff") == 0){
1650 printf("%s: link dd/ff dd/dd/ffff succeeded!\n", s);
1651 exit(1);
1652 }
1653 if(mkdir("dd/ff/ff") == 0){
1654 printf("%s: mkdir dd/ff/ff succeeded!\n", s);
1655 exit(1);
1656 }
1657 if(mkdir("dd/xx/ff") == 0){
1658 printf("%s: mkdir dd/xx/ff succeeded!\n", s);
1659 exit(1);
1660 }
1661 if(mkdir("dd/dd/ffff") == 0){
1662 printf("%s: mkdir dd/dd/ffff succeeded!\n", s);
1663 exit(1);
1664 }
1665 if(unlink("dd/xx/ff") == 0){
1666 printf("%s: unlink dd/xx/ff succeeded!\n", s);
1667 exit(1);
1668 }
1669 if(unlink("dd/ff/ff") == 0){
1670 printf("%s: unlink dd/ff/ff succeeded!\n", s);
1671 exit(1);
1672 }
1673 if(chdir("dd/ff") == 0){
1674 printf("%s: chdir dd/ff succeeded!\n", s);
1675 exit(1);
1676 }
1677 if(chdir("dd/xx") == 0){
1678 printf("%s: chdir dd/xx succeeded!\n", s);
1679 exit(1);
1680 }
1681
1682 if(unlink("dd/dd/ffff") != 0){
1683 printf("%s: unlink dd/dd/ff failed\n", s);
1684 exit(1);
1685 }
1686 if(unlink("dd/ff") != 0){
1687 printf("%s: unlink dd/ff failed\n", s);
1688 exit(1);
1689 }
1690 if(unlink("dd") == 0){
1691 printf("%s: unlink non-empty dd succeeded!\n", s);
1692 exit(1);
1693 }
1694 if(unlink("dd/dd") < 0){
1695 printf("%s: unlink dd/dd failed\n", s);
1696 exit(1);
1697 }
1698 if(unlink("dd") < 0){
1699 printf("%s: unlink dd failed\n", s);
1700 exit(1);
1701 }
1702 }
1703
1704
1705 void
1706 bigwrite(char *s)
1707 {
1708 int fd, sz;
1709
1710 unlink("bigwrite");
1711 for(sz = 499; sz < (MAXOPBLOCKS+2)*BSIZE; sz += 471){
1712 fd = open("bigwrite", O_CREATE | O_RDWR);
1713 if(fd < 0){
1714 printf("%s: cannot create bigwrite\n", s);
1715 exit(1);
1716 }
1717 int i;
1718 for(i = 0; i < 2; i++){
1719 int cc = write(fd, buf, sz);
1720 if(cc != sz){
1721 printf("%s: write(%d) ret %d\n", s, sz, cc);
1722 exit(1);
1723 }
1724 }
1725 close(fd);
1726 unlink("bigwrite");
1727 }
1728 }
1729
1730
1731 void
1732 bigfile(char *s)
1733 {
1734 enum { N = 20, SZ=600 };
1735 int fd, i, total, cc;
1736
1737 unlink("bigfile.dat");
1738 fd = open("bigfile.dat", O_CREATE | O_RDWR);
1739 if(fd < 0){
1740 printf("%s: cannot create bigfile", s);
1741 exit(1);
1742 }
1743 for(i = 0; i < N; i++){
1744 memset(buf, i, SZ);
1745 if(write(fd, buf, SZ) != SZ){
1746 printf("%s: write bigfile failed\n", s);
1747 exit(1);
1748 }
1749 }
1750 close(fd);
1751
1752 fd = open("bigfile.dat", 0);
1753 if(fd < 0){
1754 printf("%s: cannot open bigfile\n", s);
1755 exit(1);
1756 }
1757 total = 0;
1758 for(i = 0; ; i++){
1759 cc = read(fd, buf, SZ/2);
1760 if(cc < 0){
1761 printf("%s: read bigfile failed\n", s);
1762 exit(1);
1763 }
1764 if(cc == 0)
1765 break;
1766 if(cc != SZ/2){
1767 printf("%s: short read bigfile\n", s);
1768 exit(1);
1769 }
1770 if(buf[0] != i/2 || buf[SZ/2-1] != i/2){
1771 printf("%s: read bigfile wrong data\n", s);
1772 exit(1);
1773 }
1774 total += cc;
1775 }
1776 close(fd);
1777 if(total != N*SZ){
1778 printf("%s: read bigfile wrong total\n", s);
1779 exit(1);
1780 }
1781 unlink("bigfile.dat");
1782 }
1783
1784 void
1785 fourteen(char *s)
1786 {
1787 int fd;
1788
1789
1790
1791 if(mkdir("12345678901234") != 0){
1792 printf("%s: mkdir 12345678901234 failed\n", s);
1793 exit(1);
1794 }
1795 if(mkdir("12345678901234/123456789012345") != 0){
1796 printf("%s: mkdir 12345678901234/123456789012345 failed\n", s);
1797 exit(1);
1798 }
1799 fd = open("123456789012345/123456789012345/123456789012345", O_CREATE);
1800 if(fd < 0){
1801 printf("%s: create 123456789012345/123456789012345/123456789012345 failed\n", s);
1802 exit(1);
1803 }
1804 close(fd);
1805 fd = open("12345678901234/12345678901234/12345678901234", 0);
1806 if(fd < 0){
1807 printf("%s: open 12345678901234/12345678901234/12345678901234 failed\n", s);
1808 exit(1);
1809 }
1810 close(fd);
1811
1812 if(mkdir("12345678901234/12345678901234") == 0){
1813 printf("%s: mkdir 12345678901234/12345678901234 succeeded!\n", s);
1814 exit(1);
1815 }
1816 if(mkdir("123456789012345/12345678901234") == 0){
1817 printf("%s: mkdir 12345678901234/123456789012345 succeeded!\n", s);
1818 exit(1);
1819 }
1820
1821
1822 unlink("123456789012345/12345678901234");
1823 unlink("12345678901234/12345678901234");
1824 unlink("12345678901234/12345678901234/12345678901234");
1825 unlink("123456789012345/123456789012345/123456789012345");
1826 unlink("12345678901234/123456789012345");
1827 unlink("12345678901234");
1828 }
1829
1830 void
1831 rmdot(char *s)
1832 {
1833 if(mkdir("dots") != 0){
1834 printf("%s: mkdir dots failed\n", s);
1835 exit(1);
1836 }
1837 if(chdir("dots") != 0){
1838 printf("%s: chdir dots failed\n", s);
1839 exit(1);
1840 }
1841 if(unlink(".") == 0){
1842 printf("%s: rm . worked!\n", s);
1843 exit(1);
1844 }
1845 if(unlink("..") == 0){
1846 printf("%s: rm .. worked!\n", s);
1847 exit(1);
1848 }
1849 if(chdir("/") != 0){
1850 printf("%s: chdir / failed\n", s);
1851 exit(1);
1852 }
1853 if(unlink("dots/.") == 0){
1854 printf("%s: unlink dots/. worked!\n", s);
1855 exit(1);
1856 }
1857 if(unlink("dots/..") == 0){
1858 printf("%s: unlink dots/.. worked!\n", s);
1859 exit(1);
1860 }
1861 if(unlink("dots") != 0){
1862 printf("%s: unlink dots failed!\n", s);
1863 exit(1);
1864 }
1865 }
1866
1867 void
1868 dirfile(char *s)
1869 {
1870 int fd;
1871
1872 fd = open("dirfile", O_CREATE);
1873 if(fd < 0){
1874 printf("%s: create dirfile failed\n", s);
1875 exit(1);
1876 }
1877 close(fd);
1878 if(chdir("dirfile") == 0){
1879 printf("%s: chdir dirfile succeeded!\n", s);
1880 exit(1);
1881 }
1882 fd = open("dirfile/xx", 0);
1883 if(fd >= 0){
1884 printf("%s: create dirfile/xx succeeded!\n", s);
1885 exit(1);
1886 }
1887 fd = open("dirfile/xx", O_CREATE);
1888 if(fd >= 0){
1889 printf("%s: create dirfile/xx succeeded!\n", s);
1890 exit(1);
1891 }
1892 if(mkdir("dirfile/xx") == 0){
1893 printf("%s: mkdir dirfile/xx succeeded!\n", s);
1894 exit(1);
1895 }
1896 if(unlink("dirfile/xx") == 0){
1897 printf("%s: unlink dirfile/xx succeeded!\n", s);
1898 exit(1);
1899 }
1900 if(link("README", "dirfile/xx") == 0){
1901 printf("%s: link to dirfile/xx succeeded!\n", s);
1902 exit(1);
1903 }
1904 if(unlink("dirfile") != 0){
1905 printf("%s: unlink dirfile failed!\n", s);
1906 exit(1);
1907 }
1908
1909 fd = open(".", O_RDWR);
1910 if(fd >= 0){
1911 printf("%s: open . for writing succeeded!\n", s);
1912 exit(1);
1913 }
1914 fd = open(".", 0);
1915 if(write(fd, "x", 1) > 0){
1916 printf("%s: write . succeeded!\n", s);
1917 exit(1);
1918 }
1919 close(fd);
1920 }
1921
1922
1923
1924 void
1925 iref(char *s)
1926 {
1927 int i, fd;
1928
1929 for(i = 0; i < NINODE + 1; i++){
1930 if(mkdir("irefd") != 0){
1931 printf("%s: mkdir irefd failed\n", s);
1932 exit(1);
1933 }
1934 if(chdir("irefd") != 0){
1935 printf("%s: chdir irefd failed\n", s);
1936 exit(1);
1937 }
1938
1939 mkdir("");
1940 link("README", "");
1941 fd = open("", O_CREATE);
1942 if(fd >= 0)
1943 close(fd);
1944 fd = open("xx", O_CREATE);
1945 if(fd >= 0)
1946 close(fd);
1947 unlink("xx");
1948 }
1949
1950
1951 for(i = 0; i < NINODE + 1; i++){
1952 chdir("..");
1953 unlink("irefd");
1954 }
1955
1956 chdir("/");
1957 }
1958
1959
1960
1961
1962 void
1963 forktest(char *s)
1964 {
1965 enum{ N = 1000 };
1966 int n, pid;
1967
1968 for(n=0; n<N; n++){
1969 pid = fork();
1970 if(pid < 0)
1971 break;
1972 if(pid == 0)
1973 exit(0);
1974 }
1975
1976 if (n == 0) {
1977 printf("%s: no fork at all!\n", s);
1978 exit(1);
1979 }
1980
1981 if(n == N){
1982 printf("%s: fork claimed to work 1000 times!\n", s);
1983 exit(1);
1984 }
1985
1986 for(; n > 0; n--){
1987 if(wait(0) < 0){
1988 printf("%s: wait stopped early\n", s);
1989 exit(1);
1990 }
1991 }
1992
1993 if(wait(0) != -1){
1994 printf("%s: wait got too many\n", s);
1995 exit(1);
1996 }
1997 }
1998
1999 void
2000 sbrkbasic(char *s)
2001 {
2002 enum { TOOMUCH=1024*1024*1024};
2003 int i, pid, xstatus;
2004 char *c, *a, *b;
2005
2006
2007 pid = fork();
2008 if(pid < 0){
2009 printf("fork failed in sbrkbasic\n");
2010 exit(1);
2011 }
2012 if(pid == 0){
2013 a = sbrk(TOOMUCH);
2014 if(a == (char*)SBRK_ERROR){
2015
2016 exit(0);
2017 }
2018
2019 for(b = a; b < a+TOOMUCH; b += PGSIZE){
2020 *b = 99;
2021 }
2022
2023
2024
2025
2026 exit(1);
2027 }
2028
2029 wait(&xstatus);
2030 if(xstatus == 1){
2031 printf("%s: too much memory allocated!\n", s);
2032 exit(1);
2033 }
2034
2035
2036 a = sbrk(0);
2037 for(i = 0; i < 5000; i++){
2038 b = sbrk(1);
2039 if(b != a){
2040 printf("%s: sbrk test failed %d %p %p\n", s, i, a, b);
2041 exit(1);
2042 }
2043 *b = 1;
2044 a = b + 1;
2045 }
2046 pid = fork();
2047 if(pid < 0){
2048 printf("%s: sbrk test fork failed\n", s);
2049 exit(1);
2050 }
2051 c = sbrk(1);
2052 c = sbrk(1);
2053 if(c != a + 1){
2054 printf("%s: sbrk test failed post-fork\n", s);
2055 exit(1);
2056 }
2057 if(pid == 0)
2058 exit(0);
2059 wait(&xstatus);
2060 exit(xstatus);
2061 }
2062
2063 void
2064 sbrkmuch(char *s)
2065 {
2066 enum { BIG=100*1024*1024 };
2067 char *c, *oldbrk, *a, *lastaddr, *p;
2068 uint64 amt;
2069
2070 oldbrk = sbrk(0);
2071
2072
2073 a = sbrk(0);
2074 amt = BIG - (uint64)a;
2075 p = sbrk(amt);
2076 if (p != a) {
2077 printf("%s: sbrk test failed to grow big address space; enough phys mem?\n", s);
2078 exit(1);
2079 }
2080
2081 lastaddr = (char*) (BIG-1);
2082 *lastaddr = 99;
2083
2084
2085 a = sbrk(0);
2086 c = sbrk(-PGSIZE);
2087 if(c == (char*)SBRK_ERROR){
2088 printf("%s: sbrk could not deallocate\n", s);
2089 exit(1);
2090 }
2091 c = sbrk(0);
2092 if(c != a - PGSIZE){
2093 printf("%s: sbrk deallocation produced wrong address, a %p c %p\n", s, a, c);
2094 exit(1);
2095 }
2096
2097
2098 a = sbrk(0);
2099 c = sbrk(PGSIZE);
2100 if(c != a || sbrk(0) != a + PGSIZE){
2101 printf("%s: sbrk re-allocation failed, a %p c %p\n", s, a, c);
2102 exit(1);
2103 }
2104 if(*lastaddr == 99){
2105
2106 printf("%s: sbrk de-allocation didn't really deallocate\n", s);
2107 exit(1);
2108 }
2109
2110 a = sbrk(0);
2111 c = sbrk(-(sbrk(0) - oldbrk));
2112 if(c != a){
2113 printf("%s: sbrk downsize failed, a %p c %p\n", s, a, c);
2114 exit(1);
2115 }
2116 }
2117
2118
2119 void
2120 kernmem(char *s)
2121 {
2122 char *a;
2123 int pid;
2124
2125 for(a = (char*)(KERNBASE); a < (char*) (KERNBASE+2000000); a += 50000){
2126 pid = fork();
2127 if(pid < 0){
2128 printf("%s: fork failed\n", s);
2129 exit(1);
2130 }
2131 if(pid == 0){
2132 printf("%s: oops could read %p = %x\n", s, a, *a);
2133 exit(1);
2134 }
2135 int xstatus;
2136 wait(&xstatus);
2137 if(xstatus != -1)
2138 exit(1);
2139 }
2140 }
2141
2142
2143 void
2144 MAXVAplus(char *s)
2145 {
2146 volatile uint64 a = MAXVA;
2147 for( ; a != 0; a <<= 1){
2148 int pid;
2149 pid = fork();
2150 if(pid < 0){
2151 printf("%s: fork failed\n", s);
2152 exit(1);
2153 }
2154 if(pid == 0){
2155 *(char*)a = 99;
2156 printf("%s: oops wrote %p\n", s, (void*)a);
2157 exit(1);
2158 }
2159 int xstatus;
2160 wait(&xstatus);
2161 if(xstatus != -1)
2162 exit(1);
2163 }
2164 }
2165
2166
2167
2168 void
2169 sbrkfail(char *s)
2170 {
2171 enum { BIG=100*1024*1024 };
2172 int i, xstatus;
2173 int fds[2];
2174 char scratch;
2175 char *c, *a;
2176 int pids[10];
2177 int pid;
2178 int failed;
2179
2180 failed = 0;
2181 if(pipe(fds) != 0){
2182 printf("%s: pipe() failed\n", s);
2183 exit(1);
2184 }
2185 for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
2186 if((pids[i] = fork()) == 0){
2187
2188 if (sbrk(BIG - (uint64)sbrk(0)) == (char*)SBRK_ERROR)
2189 write(fds[1], "0", 1);
2190 else
2191 write(fds[1], "1", 1);
2192
2193 for(;;) pause(1000);
2194 }
2195 if(pids[i] != -1) {
2196 read(fds[0], &scratch, 1);
2197 if(scratch == '0')
2198 failed = 1;
2199 }
2200 }
2201 if(!failed) {
2202 printf("%s: no allocation failed; allocate more?\n", s);
2203 }
2204
2205
2206
2207 c = sbrk(PGSIZE);
2208 for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
2209 if(pids[i] == -1)
2210 continue;
2211 kill(pids[i]);
2212 wait(0);
2213 }
2214 if(c == (char*)SBRK_ERROR){
2215 printf("%s: failed sbrk leaked memory\n", s);
2216 exit(1);
2217 }
2218
2219
2220 pid = fork();
2221 if(pid < 0){
2222 printf("%s: fork failed\n", s);
2223 exit(1);
2224 }
2225 if(pid == 0){
2226
2227 a = sbrk(10*BIG);
2228 if(a == (char*)SBRK_ERROR){
2229 exit(0);
2230 }
2231 printf("%s: allocate a lot of memory succeeded %d\n", s, 10*BIG);
2232 exit(1);
2233 }
2234 wait(&xstatus);
2235 if(xstatus != 0)
2236 exit(1);
2237 }
2238
2239
2240
2241 void
2242 sbrkarg(char *s)
2243 {
2244 char *a;
2245 int fd, n;
2246
2247 a = sbrk(PGSIZE);
2248 fd = open("sbrk", O_CREATE|O_WRONLY);
2249 unlink("sbrk");
2250 if(fd < 0) {
2251 printf("%s: open sbrk failed\n", s);
2252 exit(1);
2253 }
2254 if ((n = write(fd, a, PGSIZE)) < 0) {
2255 printf("%s: write sbrk failed\n", s);
2256 exit(1);
2257 }
2258 close(fd);
2259
2260
2261 a = sbrk(PGSIZE);
2262 if(pipe((int *) a) != 0){
2263 printf("%s: pipe() failed\n", s);
2264 exit(1);
2265 }
2266 }
2267
2268 void
2269 validatetest(char *s)
2270 {
2271 int hi;
2272 uint64 p;
2273
2274 hi = 1100*1024;
2275 for(p = 0; p <= (uint)hi; p += PGSIZE){
2276
2277 if(link("nosuchfile", (char*)p) != -1){
2278 printf("%s: link should not succeed\n", s);
2279 exit(1);
2280 }
2281 }
2282 }
2283
2284
2285 char uninit[10000];
2286 void
2287 bsstest(char *s)
2288 {
2289 int i;
2290
2291 for(i = 0; i < sizeof(uninit); i++){
2292 if(uninit[i] != '\0'){
2293 printf("%s: bss test failed\n", s);
2294 exit(1);
2295 }
2296 }
2297 }
2298
2299
2300
2301
2302 void
2303 bigargtest(char *s)
2304 {
2305 int pid, fd, xstatus;
2306
2307 unlink("bigarg-ok");
2308 pid = fork();
2309 if(pid == 0){
2310 static char *args[MAXARG];
2311 int i;
2312 char big[400];
2313 memset(big, ' ', sizeof(big));
2314 big[sizeof(big)-1] = '\0';
2315 for(i = 0; i < MAXARG-1; i++)
2316 args[i] = big;
2317 args[MAXARG-1] = 0;
2318
2319
2320 exec("echo", args);
2321 fd = open("bigarg-ok", O_CREATE);
2322 close(fd);
2323 exit(0);
2324 } else if(pid < 0){
2325 printf("%s: bigargtest: fork failed\n", s);
2326 exit(1);
2327 }
2328
2329 wait(&xstatus);
2330 if(xstatus != 0)
2331 exit(xstatus);
2332 fd = open("bigarg-ok", 0);
2333 if(fd < 0){
2334 printf("%s: bigarg test failed!\n", s);
2335 exit(1);
2336 }
2337 close(fd);
2338 }
2339
2340
2341
2342 void
2343 fsfull()
2344 {
2345 int nfiles;
2346 int fsblocks = 0;
2347
2348 printf("fsfull test\n");
2349
2350 for(nfiles = 0; ; nfiles++){
2351 char name[64];
2352 name[0] = 'f';
2353 name[1] = '0' + nfiles / 1000;
2354 name[2] = '0' + (nfiles % 1000) / 100;
2355 name[3] = '0' + (nfiles % 100) / 10;
2356 name[4] = '0' + (nfiles % 10);
2357 name[5] = '\0';
2358 printf("writing %s\n", name);
2359 int fd = open(name, O_CREATE|O_RDWR);
2360 if(fd < 0){
2361 printf("open %s failed\n", name);
2362 break;
2363 }
2364 int total = 0;
2365 while(1){
2366 int cc = write(fd, buf, BSIZE);
2367 if(cc < BSIZE)
2368 break;
2369 total += cc;
2370 fsblocks++;
2371 }
2372 printf("wrote %d bytes\n", total);
2373 close(fd);
2374 if(total == 0)
2375 break;
2376 }
2377
2378 while(nfiles >= 0){
2379 char name[64];
2380 name[0] = 'f';
2381 name[1] = '0' + nfiles / 1000;
2382 name[2] = '0' + (nfiles % 1000) / 100;
2383 name[3] = '0' + (nfiles % 100) / 10;
2384 name[4] = '0' + (nfiles % 10);
2385 name[5] = '\0';
2386 unlink(name);
2387 nfiles--;
2388 }
2389
2390 printf("fsfull test finished\n");
2391 }
2392
2393 void argptest(char *s)
2394 {
2395 int fd;
2396 fd = open("init", O_RDONLY);
2397 if (fd < 0) {
2398 printf("%s: open failed\n", s);
2399 exit(1);
2400 }
2401 read(fd, sbrk(0) - 1, -1);
2402 close(fd);
2403 }
2404
2405
2406
2407 void
2408 stacktest(char *s)
2409 {
2410 int pid;
2411 int xstatus;
2412
2413 pid = fork();
2414 if(pid == 0) {
2415 char *sp = (char *) r_sp();
2416 sp -= USERSTACK*PGSIZE;
2417
2418 printf("%s: stacktest: read below stack %d\n", s, *sp);
2419 exit(1);
2420 } else if(pid < 0){
2421 printf("%s: fork failed\n", s);
2422 exit(1);
2423 }
2424 wait(&xstatus);
2425 if(xstatus == -1)
2426 exit(0);
2427 else
2428 exit(xstatus);
2429 }
2430
2431
2432
2433 void
2434 nowrite(char *s)
2435 {
2436 int pid;
2437 int xstatus;
2438 uint64 addrs[] = { 0, 0x80000000LL, 0x3fffffe000, 0x3ffffff000, 0x4000000000,
2439 0xffffffffffffffff };
2440
2441 for(int ai = 0; ai < sizeof(addrs)/sizeof(addrs[0]); ai++){
2442 pid = fork();
2443 if(pid == 0) {
2444 volatile int *addr = (int *) addrs[ai];
2445 *addr = 10;
2446 printf("%s: write to %p did not fail!\n", s, addr);
2447 exit(0);
2448 } else if(pid < 0){
2449 printf("%s: fork failed\n", s);
2450 exit(1);
2451 }
2452 wait(&xstatus);
2453 if(xstatus == 0){
2454
2455 exit(1);
2456 }
2457 }
2458 exit(0);
2459 }
2460
2461
2462
2463
2464 void *big = (void*) 0xeaeb0b5b00002f5e;
2465 void
2466 pgbug(char *s)
2467 {
2468 char *argv[1];
2469 argv[0] = 0;
2470 exec(big, argv);
2471 pipe(big);
2472
2473 exit(0);
2474 }
2475
2476
2477
2478
2479 void
2480 sbrkbugs(char *s)
2481 {
2482 int pid = fork();
2483 if(pid < 0){
2484 printf("fork failed\n");
2485 exit(1);
2486 }
2487 if(pid == 0){
2488 int sz = (uint64) sbrk(0);
2489
2490
2491
2492 sbrk(-sz);
2493
2494 exit(0);
2495 }
2496 wait(0);
2497
2498 pid = fork();
2499 if(pid < 0){
2500 printf("fork failed\n");
2501 exit(1);
2502 }
2503 if(pid == 0){
2504 int sz = (uint64) sbrk(0);
2505
2506
2507
2508 sbrk(-(sz - 3500));
2509 exit(0);
2510 }
2511 wait(0);
2512
2513 pid = fork();
2514 if(pid < 0){
2515 printf("fork failed\n");
2516 exit(1);
2517 }
2518 if(pid == 0){
2519
2520 sbrk((10*PGSIZE + 2048) - (uint64)sbrk(0));
2521
2522
2523
2524
2525 sbrk(-10);
2526
2527 exit(0);
2528 }
2529 wait(0);
2530
2531 exit(0);
2532 }
2533
2534
2535
2536
2537 void
2538 sbrklast(char *s)
2539 {
2540 uint64 top = (uint64) sbrk(0);
2541 if((top % PGSIZE) != 0)
2542 sbrk(PGSIZE - (top % PGSIZE));
2543 sbrk(PGSIZE);
2544 sbrk(10);
2545 sbrk(-20);
2546 top = (uint64) sbrk(0);
2547 char *p = (char *) (top - 64);
2548 p[0] = 'x';
2549 p[1] = '\0';
2550 int fd = open(p, O_RDWR|O_CREATE);
2551 write(fd, p, 1);
2552 close(fd);
2553 fd = open(p, O_RDWR);
2554 p[0] = '\0';
2555 read(fd, p, 1);
2556 if(p[0] != 'x')
2557 exit(1);
2558 }
2559
2560
2561
2562
2563 void
2564 sbrk8000(char *s)
2565 {
2566 sbrk(0x80000004);
2567 volatile char *top = sbrk(0);
2568 *(top-1) = *(top-1) + 1;
2569 }
2570
2571
2572
2573
2574
2575 void
2576 badarg(char *s)
2577 {
2578 for(int i = 0; i < 50000; i++){
2579 char *argv[2];
2580 argv[0] = (char*)0xffffffff;
2581 argv[1] = 0;
2582 exec("echo", argv);
2583 }
2584
2585 exit(0);
2586 }
2587
2588 #define REGION_SZ (1024 * 1024 * 1024)
2589
2590
2591
2592 void
2593 lazy_alloc(char *s)
2594 {
2595 char *i, *prev_end, *new_end;
2596
2597 prev_end = sbrklazy(REGION_SZ);
2598 if (prev_end == (char *) SBRK_ERROR) {
2599 printf("sbrklazy() failed\n");
2600 exit(1);
2601 }
2602 new_end = prev_end + REGION_SZ;
2603
2604 for (i = prev_end + PGSIZE; i < new_end; i += 64 * PGSIZE)
2605 *(char **)i = i;
2606
2607 for (i = prev_end + PGSIZE; i < new_end; i += 64 * PGSIZE) {
2608 if (*(char **)i != i) {
2609 printf("failed to read value from memory\n");
2610 exit(1);
2611 }
2612 }
2613
2614 exit(0);
2615 }
2616
2617
2618
2619
2620 void
2621 lazy_unmap(char *s)
2622 {
2623 int pid;
2624 char *i, *prev_end, *new_end;
2625
2626 prev_end = sbrklazy(REGION_SZ);
2627 if (prev_end == (char*)SBRK_ERROR) {
2628 printf("sbrklazy() failed\n");
2629 exit(1);
2630 }
2631 new_end = prev_end + REGION_SZ;
2632
2633 for (i = prev_end + PGSIZE; i < new_end; i += PGSIZE * PGSIZE)
2634 *(char **)i = i;
2635
2636 for (i = prev_end + PGSIZE; i < new_end; i += PGSIZE * PGSIZE) {
2637 pid = fork();
2638 if (pid < 0) {
2639 printf("error forking\n");
2640 exit(1);
2641 } else if (pid == 0) {
2642 sbrklazy(-1L * REGION_SZ);
2643 *(char **)i = i;
2644 exit(0);
2645 } else {
2646 int status;
2647 wait(&status);
2648 if (status == 0) {
2649 printf("memory not unmapped\n");
2650 exit(1);
2651 }
2652 }
2653 }
2654
2655 exit(0);
2656 }
2657
2658 void
2659 lazy_copy(char *s)
2660 {
2661
2662 {
2663 char *p = sbrk(0);
2664 sbrklazy(4*PGSIZE);
2665 open(p + 8192, 0);
2666 }
2667
2668 {
2669 void *xx = sbrk(0);
2670 void *ret = sbrk(-(((uint64) xx)+1));
2671 if(ret != xx){
2672 printf("sbrk(sbrk(0)+1) returned %p, not old sz\n", ret);
2673 exit(1);
2674 }
2675 }
2676
2677
2678
2679 unsigned long bad[] = {
2680 0x3fffffc000,
2681 0x3fffffd000,
2682 0x3fffffe000,
2683 0x3ffffff000,
2684 0x4000000000,
2685 0x8000000000,
2686 };
2687 for(int i = 0; i < sizeof(bad)/sizeof(bad[0]); i++){
2688 int fd = open("README", 0);
2689 if(fd < 0) { printf("cannot open README\n"); exit(1); }
2690 if(read(fd, (char*)bad[i], 512) >= 0) { printf("read succeeded\n"); exit(1); }
2691 close(fd);
2692 fd = open("junk", O_CREATE|O_RDWR|O_TRUNC);
2693 if(fd < 0) { printf("cannot open junk\n"); exit(1); }
2694 if(write(fd, (char*)bad[i], 512) >= 0) { printf("write succeeded\n"); exit(1); }
2695 close(fd);
2696 }
2697
2698 exit(0);
2699 }
2700
2701 struct test {
2702 void (*f)(char *);
2703 char *s;
2704 } quicktests[] = {
2705 {copyin, "copyin"},
2706 {copyout, "copyout"},
2707 {copyinstr1, "copyinstr1"},
2708 {copyinstr2, "copyinstr2"},
2709 {copyinstr3, "copyinstr3"},
2710 {rwsbrk, "rwsbrk" },
2711 {truncate1, "truncate1"},
2712 {truncate2, "truncate2"},
2713 {truncate3, "truncate3"},
2714 {openiputtest, "openiput"},
2715 {exitiputtest, "exitiput"},
2716 {iputtest, "iput"},
2717 {opentest, "opentest"},
2718 {writetest, "writetest"},
2719 {writebig, "writebig"},
2720 {createtest, "createtest"},
2721 {dirtest, "dirtest"},
2722 {exectest, "exectest"},
2723 {pipe1, "pipe1"},
2724 {killstatus, "killstatus"},
2725 {preempt, "preempt"},
2726 {exitwait, "exitwait"},
2727 {reparent, "reparent" },
2728 {twochildren, "twochildren"},
2729 {forkfork, "forkfork"},
2730 {forkforkfork, "forkforkfork"},
2731 {reparent2, "reparent2"},
2732 {mem, "mem"},
2733 {sharedfd, "sharedfd"},
2734 {fourfiles, "fourfiles"},
2735 {createdelete, "createdelete"},
2736 {unlinkread, "unlinkread"},
2737 {linktest, "linktest"},
2738 {concreate, "concreate"},
2739 {linkunlink, "linkunlink"},
2740 {subdir, "subdir"},
2741 {bigwrite, "bigwrite"},
2742 {bigfile, "bigfile"},
2743 {fourteen, "fourteen"},
2744 {rmdot, "rmdot"},
2745 {dirfile, "dirfile"},
2746 {iref, "iref"},
2747 {forktest, "forktest"},
2748 {sbrkbasic, "sbrkbasic"},
2749 {sbrkmuch, "sbrkmuch"},
2750 {kernmem, "kernmem"},
2751 {MAXVAplus, "MAXVAplus"},
2752 {sbrkfail, "sbrkfail"},
2753 {sbrkarg, "sbrkarg"},
2754 {validatetest, "validatetest"},
2755 {bsstest, "bsstest"},
2756 {bigargtest, "bigargtest"},
2757 {argptest, "argptest"},
2758 {stacktest, "stacktest"},
2759 {nowrite, "nowrite"},
2760 {pgbug, "pgbug" },
2761 {sbrkbugs, "sbrkbugs" },
2762 {sbrklast, "sbrklast"},
2763 {sbrk8000, "sbrk8000"},
2764 {badarg, "badarg" },
2765 {lazy_alloc, "lazy_alloc"},
2766 {lazy_unmap, "lazy_unmap"},
2767 {lazy_copy, "lazy_copy"},
2768 { 0, 0},
2769 };
2770
2771
2772
2773
2774
2775
2776 void
2777 bigdir(char *s)
2778 {
2779 enum { N = 500 };
2780 int i, fd;
2781 char name[10];
2782
2783 unlink("bd");
2784
2785 fd = open("bd", O_CREATE);
2786 if(fd < 0){
2787 printf("%s: bigdir create failed\n", s);
2788 exit(1);
2789 }
2790 close(fd);
2791
2792 for(i = 0; i < N; i++){
2793 name[0] = 'x';
2794 name[1] = '0' + (i / 64);
2795 name[2] = '0' + (i % 64);
2796 name[3] = '\0';
2797 if(link("bd", name) != 0){
2798 printf("%s: bigdir i=%d link(bd, %s) failed\n", s, i, name);
2799 exit(1);
2800 }
2801 }
2802
2803 unlink("bd");
2804 for(i = 0; i < N; i++){
2805 name[0] = 'x';
2806 name[1] = '0' + (i / 64);
2807 name[2] = '0' + (i % 64);
2808 name[3] = '\0';
2809 if(unlink(name) != 0){
2810 printf("%s: bigdir unlink failed", s);
2811 exit(1);
2812 }
2813 }
2814 }
2815
2816
2817
2818 void
2819 manywrites(char *s)
2820 {
2821 int nchildren = 4;
2822 int howmany = 30;
2823
2824 for(int ci = 0; ci < nchildren; ci++){
2825 int pid = fork();
2826 if(pid < 0){
2827 printf("fork failed\n");
2828 exit(1);
2829 }
2830
2831 if(pid == 0){
2832 char name[3];
2833 name[0] = 'b';
2834 name[1] = 'a' + ci;
2835 name[2] = '\0';
2836 unlink(name);
2837
2838 for(int iters = 0; iters < howmany; iters++){
2839 for(int i = 0; i < ci+1; i++){
2840 int fd = open(name, O_CREATE | O_RDWR);
2841 if(fd < 0){
2842 printf("%s: cannot create %s\n", s, name);
2843 exit(1);
2844 }
2845 int sz = sizeof(buf);
2846 int cc = write(fd, buf, sz);
2847 if(cc != sz){
2848 printf("%s: write(%d) ret %d\n", s, sz, cc);
2849 exit(1);
2850 }
2851 close(fd);
2852 }
2853 unlink(name);
2854 }
2855
2856 unlink(name);
2857 exit(0);
2858 }
2859 }
2860
2861 for(int ci = 0; ci < nchildren; ci++){
2862 int st = 0;
2863 wait(&st);
2864 if(st != 0)
2865 exit(st);
2866 }
2867 exit(0);
2868 }
2869
2870
2871
2872
2873
2874
2875 void
2876 badwrite(char *s)
2877 {
2878 int assumed_free = 600;
2879
2880 unlink("junk");
2881 for(int i = 0; i < assumed_free; i++){
2882 int fd = open("junk", O_CREATE|O_WRONLY);
2883 if(fd < 0){
2884 printf("open junk failed\n");
2885 exit(1);
2886 }
2887 write(fd, (char*)0xffffffffffL, 1);
2888 close(fd);
2889 unlink("junk");
2890 }
2891
2892 int fd = open("junk", O_CREATE|O_WRONLY);
2893 if(fd < 0){
2894 printf("open junk failed\n");
2895 exit(1);
2896 }
2897 if(write(fd, "x", 1) != 1){
2898 printf("write failed\n");
2899 exit(1);
2900 }
2901 close(fd);
2902 unlink("junk");
2903
2904 exit(0);
2905 }
2906
2907
2908
2909
2910 void
2911 execout(char *s)
2912 {
2913 for(int avail = 0; avail < 15; avail++){
2914 int pid = fork();
2915 if(pid < 0){
2916 printf("fork failed\n");
2917 exit(1);
2918 } else if(pid == 0){
2919
2920 while(1){
2921 char *a = sbrk(PGSIZE);
2922 if(a == SBRK_ERROR)
2923 break;
2924 *(a + PGSIZE - 1) = 1;
2925 }
2926
2927
2928
2929 for(int i = 0; i < avail; i++)
2930 sbrk(-PGSIZE);
2931
2932 close(1);
2933 char *args[] = { "echo", "x", 0 };
2934 exec("echo", args);
2935 exit(0);
2936 } else {
2937 wait((int*)0);
2938 }
2939 }
2940
2941 exit(0);
2942 }
2943
2944
2945 void
2946 diskfull(char *s)
2947 {
2948 int fi;
2949 int done = 0;
2950
2951 unlink("diskfulldir");
2952
2953 for(fi = 0; done == 0 && '0' + fi < 0177; fi++){
2954 char name[32];
2955 name[0] = 'b';
2956 name[1] = 'i';
2957 name[2] = 'g';
2958 name[3] = '0' + fi;
2959 name[4] = '\0';
2960 unlink(name);
2961 int fd = open(name, O_CREATE|O_RDWR|O_TRUNC);
2962 if(fd < 0){
2963
2964 printf("%s: could not create file %s\n", s, name);
2965 done = 1;
2966 break;
2967 }
2968 for(int i = 0; i < MAXFILE; i++){
2969 char buf[BSIZE];
2970 if(write(fd, buf, BSIZE) != BSIZE){
2971 done = 1;
2972 close(fd);
2973 break;
2974 }
2975 }
2976 close(fd);
2977 }
2978
2979
2980
2981
2982
2983 int nzz = 128;
2984 for(int i = 0; i < nzz; i++){
2985 char name[32];
2986 name[0] = 'z';
2987 name[1] = 'z';
2988 name[2] = '0' + (i / 32);
2989 name[3] = '0' + (i % 32);
2990 name[4] = '\0';
2991 unlink(name);
2992 int fd = open(name, O_CREATE|O_RDWR|O_TRUNC);
2993 if(fd < 0)
2994 break;
2995 close(fd);
2996 }
2997
2998
2999 if(mkdir("diskfulldir") == 0)
3000 printf("%s: mkdir(diskfulldir) unexpectedly succeeded!\n", s);
3001
3002 unlink("diskfulldir");
3003
3004 for(int i = 0; i < nzz; i++){
3005 char name[32];
3006 name[0] = 'z';
3007 name[1] = 'z';
3008 name[2] = '0' + (i / 32);
3009 name[3] = '0' + (i % 32);
3010 name[4] = '\0';
3011 unlink(name);
3012 }
3013
3014 for(int i = 0; '0' + i < 0177; i++){
3015 char name[32];
3016 name[0] = 'b';
3017 name[1] = 'i';
3018 name[2] = 'g';
3019 name[3] = '0' + i;
3020 name[4] = '\0';
3021 unlink(name);
3022 }
3023 }
3024
3025 void
3026 outofinodes(char *s)
3027 {
3028 int nzz = 32*32;
3029 for(int i = 0; i < nzz; i++){
3030 char name[32];
3031 name[0] = 'z';
3032 name[1] = 'z';
3033 name[2] = '0' + (i / 32);
3034 name[3] = '0' + (i % 32);
3035 name[4] = '\0';
3036 unlink(name);
3037 int fd = open(name, O_CREATE|O_RDWR|O_TRUNC);
3038 if(fd < 0){
3039
3040 break;
3041 }
3042 close(fd);
3043 }
3044
3045 for(int i = 0; i < nzz; i++){
3046 char name[32];
3047 name[0] = 'z';
3048 name[1] = 'z';
3049 name[2] = '0' + (i / 32);
3050 name[3] = '0' + (i % 32);
3051 name[4] = '\0';
3052 unlink(name);
3053 }
3054 }
3055
3056 struct test slowtests[] = {
3057 {bigdir, "bigdir"},
3058 {manywrites, "manywrites"},
3059 {badwrite, "badwrite" },
3060 {execout, "execout"},
3061 {diskfull, "diskfull"},
3062 {outofinodes, "outofinodes"},
3063
3064 { 0, 0},
3065 };
3066
3067
3068
3069
3070
3071
3072
3073 int
3074 run(void f(char *), char *s) {
3075 int pid;
3076 int xstatus;
3077
3078 printf("test %s: ", s);
3079 if((pid = fork()) < 0) {
3080 printf("runtest: fork error\n");
3081 exit(1);
3082 }
3083 if(pid == 0) {
3084 f(s);
3085 exit(0);
3086 } else {
3087 wait(&xstatus);
3088 if(xstatus != 0)
3089 printf("FAILED\n");
3090 else
3091 printf("OK\n");
3092 return xstatus == 0;
3093 }
3094 }
3095
3096 int
3097 runtests(struct test *tests, char *justone, int continuous) {
3098 int ntests = 0;
3099 for (struct test *t = tests; t->s != 0; t++) {
3100 if((justone == 0) || strcmp(t->s, justone) == 0) {
3101 ntests++;
3102 if(!run(t->f, t->s)){
3103 if(continuous != 2){
3104 printf("SOME TESTS FAILED\n");
3105 return -1;
3106 }
3107 }
3108 }
3109 }
3110 return ntests;
3111 }
3112
3113
3114
3115 int
3116 countfree()
3117 {
3118 int n = 0;
3119 uint64 sz0 = (uint64)sbrk(0);
3120 while(1){
3121 char *a = sbrk(PGSIZE);
3122 if(a == SBRK_ERROR){
3123 break;
3124 }
3125 n += 1;
3126 }
3127 sbrk(-((uint64)sbrk(0) - sz0));
3128 return n;
3129 }
3130
3131 int
3132 drivetests(int quick, int continuous, char *justone) {
3133 do {
3134 printf("usertests starting\n");
3135 int free0 = countfree();
3136 int free1 = 0;
3137 int ntests = 0;
3138 int n;
3139 n = runtests(quicktests, justone, continuous);
3140 if (n < 0) {
3141 if(continuous != 2) {
3142 return 1;
3143 }
3144 } else {
3145 ntests += n;
3146 }
3147 if(!quick) {
3148 if (justone == 0)
3149 printf("usertests slow tests starting\n");
3150 n = runtests(slowtests, justone, continuous);
3151 if (n < 0) {
3152 if(continuous != 2) {
3153 return 1;
3154 }
3155 } else {
3156 ntests += n;
3157 }
3158 }
3159 if((free1 = countfree()) < free0) {
3160 printf("FAILED -- lost some free pages %d (out of %d)\n", free1, free0);
3161 if(continuous != 2) {
3162 return 1;
3163 }
3164 }
3165 if (justone != 0 && ntests == 0) {
3166 printf("NO TESTS EXECUTED\n");
3167 return 1;
3168 }
3169 } while(continuous);
3170 return 0;
3171 }
3172
3173 int
3174 main(int argc, char *argv[])
3175 {
3176 int continuous = 0;
3177 int quick = 0;
3178 char *justone = 0;
3179
3180 if(argc == 2 && strcmp(argv[1], "-q") == 0){
3181 quick = 1;
3182 } else if(argc == 2 && strcmp(argv[1], "-c") == 0){
3183 continuous = 1;
3184 } else if(argc == 2 && strcmp(argv[1], "-C") == 0){
3185 continuous = 2;
3186 } else if(argc == 2 && argv[1][0] != '-'){
3187 justone = argv[1];
3188 } else if(argc > 1){
3189 printf("Usage: usertests [-c] [-C] [-q] [testname]\n");
3190 exit(1);
3191 }
3192 if (drivetests(quick, continuous, justone)) {
3193 exit(1);
3194 }
3195 printf("ALL TESTS PASSED\n");
3196 exit(0);
3197 }