xref: /xv6-public/usertests.c (revision 907f23a5)
1 #include "param.h"
2 #include "types.h"
3 #include "stat.h"
4 #include "user.h"
5 #include "fs.h"
6 #include "fcntl.h"
7 #include "syscall.h"
8 #include "traps.h"
9 #include "memlayout.h"
10 
11 char buf[8192];
12 char name[3];
13 char *echoargv[] = { "echo", "ALL", "TESTS", "PASSED", 0 };
14 int stdout = 1;
15 
16 // does chdir() call iput(p->cwd) in a transaction?
17 void
iputtest(void)18 iputtest(void)
19 {
20   printf(stdout, "iput test\n");
21 
22   if(mkdir("iputdir") < 0){
23     printf(stdout, "mkdir failed\n");
24     exit();
25   }
26   if(chdir("iputdir") < 0){
27     printf(stdout, "chdir iputdir failed\n");
28     exit();
29   }
30   if(unlink("../iputdir") < 0){
31     printf(stdout, "unlink ../iputdir failed\n");
32     exit();
33   }
34   if(chdir("/") < 0){
35     printf(stdout, "chdir / failed\n");
36     exit();
37   }
38   printf(stdout, "iput test ok\n");
39 }
40 
41 // does exit() call iput(p->cwd) in a transaction?
42 void
exitiputtest(void)43 exitiputtest(void)
44 {
45   int pid;
46 
47   printf(stdout, "exitiput test\n");
48 
49   pid = fork();
50   if(pid < 0){
51     printf(stdout, "fork failed\n");
52     exit();
53   }
54   if(pid == 0){
55     if(mkdir("iputdir") < 0){
56       printf(stdout, "mkdir failed\n");
57       exit();
58     }
59     if(chdir("iputdir") < 0){
60       printf(stdout, "child chdir failed\n");
61       exit();
62     }
63     if(unlink("../iputdir") < 0){
64       printf(stdout, "unlink ../iputdir failed\n");
65       exit();
66     }
67     exit();
68   }
69   wait();
70   printf(stdout, "exitiput test ok\n");
71 }
72 
73 // does the error path in open() for attempt to write a
74 // directory call iput() in a transaction?
75 // needs a hacked kernel that pauses just after the namei()
76 // call in sys_open():
77 //    if((ip = namei(path)) == 0)
78 //      return -1;
79 //    {
80 //      int i;
81 //      for(i = 0; i < 10000; i++)
82 //        yield();
83 //    }
84 void
openiputtest(void)85 openiputtest(void)
86 {
87   int pid;
88 
89   printf(stdout, "openiput test\n");
90   if(mkdir("oidir") < 0){
91     printf(stdout, "mkdir oidir failed\n");
92     exit();
93   }
94   pid = fork();
95   if(pid < 0){
96     printf(stdout, "fork failed\n");
97     exit();
98   }
99   if(pid == 0){
100     int fd = open("oidir", O_RDWR);
101     if(fd >= 0){
102       printf(stdout, "open directory for write succeeded\n");
103       exit();
104     }
105     exit();
106   }
107   sleep(1);
108   if(unlink("oidir") != 0){
109     printf(stdout, "unlink failed\n");
110     exit();
111   }
112   wait();
113   printf(stdout, "openiput test ok\n");
114 }
115 
116 // simple file system tests
117 
118 void
opentest(void)119 opentest(void)
120 {
121   int fd;
122 
123   printf(stdout, "open test\n");
124   fd = open("echo", 0);
125   if(fd < 0){
126     printf(stdout, "open echo failed!\n");
127     exit();
128   }
129   close(fd);
130   fd = open("doesnotexist", 0);
131   if(fd >= 0){
132     printf(stdout, "open doesnotexist succeeded!\n");
133     exit();
134   }
135   printf(stdout, "open test ok\n");
136 }
137 
138 void
writetest(void)139 writetest(void)
140 {
141   int fd;
142   int i;
143 
144   printf(stdout, "small file test\n");
145   fd = open("small", O_CREATE|O_RDWR);
146   if(fd >= 0){
147     printf(stdout, "creat small succeeded; ok\n");
148   } else {
149     printf(stdout, "error: creat small failed!\n");
150     exit();
151   }
152   for(i = 0; i < 100; i++){
153     if(write(fd, "aaaaaaaaaa", 10) != 10){
154       printf(stdout, "error: write aa %d new file failed\n", i);
155       exit();
156     }
157     if(write(fd, "bbbbbbbbbb", 10) != 10){
158       printf(stdout, "error: write bb %d new file failed\n", i);
159       exit();
160     }
161   }
162   printf(stdout, "writes ok\n");
163   close(fd);
164   fd = open("small", O_RDONLY);
165   if(fd >= 0){
166     printf(stdout, "open small succeeded ok\n");
167   } else {
168     printf(stdout, "error: open small failed!\n");
169     exit();
170   }
171   i = read(fd, buf, 2000);
172   if(i == 2000){
173     printf(stdout, "read succeeded ok\n");
174   } else {
175     printf(stdout, "read failed\n");
176     exit();
177   }
178   close(fd);
179 
180   if(unlink("small") < 0){
181     printf(stdout, "unlink small failed\n");
182     exit();
183   }
184   printf(stdout, "small file test ok\n");
185 }
186 
187 void
writetest1(void)188 writetest1(void)
189 {
190   int i, fd, n;
191 
192   printf(stdout, "big files test\n");
193 
194   fd = open("big", O_CREATE|O_RDWR);
195   if(fd < 0){
196     printf(stdout, "error: creat big failed!\n");
197     exit();
198   }
199 
200   for(i = 0; i < MAXFILE; i++){
201     ((int*)buf)[0] = i;
202     if(write(fd, buf, 512) != 512){
203       printf(stdout, "error: write big file failed\n", i);
204       exit();
205     }
206   }
207 
208   close(fd);
209 
210   fd = open("big", O_RDONLY);
211   if(fd < 0){
212     printf(stdout, "error: open big failed!\n");
213     exit();
214   }
215 
216   n = 0;
217   for(;;){
218     i = read(fd, buf, 512);
219     if(i == 0){
220       if(n == MAXFILE - 1){
221         printf(stdout, "read only %d blocks from big", n);
222         exit();
223       }
224       break;
225     } else if(i != 512){
226       printf(stdout, "read failed %d\n", i);
227       exit();
228     }
229     if(((int*)buf)[0] != n){
230       printf(stdout, "read content of block %d is %d\n",
231              n, ((int*)buf)[0]);
232       exit();
233     }
234     n++;
235   }
236   close(fd);
237   if(unlink("big") < 0){
238     printf(stdout, "unlink big failed\n");
239     exit();
240   }
241   printf(stdout, "big files ok\n");
242 }
243 
244 void
createtest(void)245 createtest(void)
246 {
247   int i, fd;
248 
249   printf(stdout, "many creates, followed by unlink test\n");
250 
251   name[0] = 'a';
252   name[2] = '\0';
253   for(i = 0; i < 52; i++){
254     name[1] = '0' + i;
255     fd = open(name, O_CREATE|O_RDWR);
256     close(fd);
257   }
258   name[0] = 'a';
259   name[2] = '\0';
260   for(i = 0; i < 52; i++){
261     name[1] = '0' + i;
262     unlink(name);
263   }
264   printf(stdout, "many creates, followed by unlink; ok\n");
265 }
266 
dirtest(void)267 void dirtest(void)
268 {
269   printf(stdout, "mkdir test\n");
270 
271   if(mkdir("dir0") < 0){
272     printf(stdout, "mkdir failed\n");
273     exit();
274   }
275 
276   if(chdir("dir0") < 0){
277     printf(stdout, "chdir dir0 failed\n");
278     exit();
279   }
280 
281   if(chdir("..") < 0){
282     printf(stdout, "chdir .. failed\n");
283     exit();
284   }
285 
286   if(unlink("dir0") < 0){
287     printf(stdout, "unlink dir0 failed\n");
288     exit();
289   }
290   printf(stdout, "mkdir test ok\n");
291 }
292 
293 void
exectest(void)294 exectest(void)
295 {
296   printf(stdout, "exec test\n");
297   if(exec("echo", echoargv) < 0){
298     printf(stdout, "exec echo failed\n");
299     exit();
300   }
301 }
302 
303 // simple fork and pipe read/write
304 
305 void
pipe1(void)306 pipe1(void)
307 {
308   int fds[2], pid;
309   int seq, i, n, cc, total;
310 
311   if(pipe(fds) != 0){
312     printf(1, "pipe() failed\n");
313     exit();
314   }
315   pid = fork();
316   seq = 0;
317   if(pid == 0){
318     close(fds[0]);
319     for(n = 0; n < 5; n++){
320       for(i = 0; i < 1033; i++)
321         buf[i] = seq++;
322       if(write(fds[1], buf, 1033) != 1033){
323         printf(1, "pipe1 oops 1\n");
324         exit();
325       }
326     }
327     exit();
328   } else if(pid > 0){
329     close(fds[1]);
330     total = 0;
331     cc = 1;
332     while((n = read(fds[0], buf, cc)) > 0){
333       for(i = 0; i < n; i++){
334         if((buf[i] & 0xff) != (seq++ & 0xff)){
335           printf(1, "pipe1 oops 2\n");
336           return;
337         }
338       }
339       total += n;
340       cc = cc * 2;
341       if(cc > sizeof(buf))
342         cc = sizeof(buf);
343     }
344     if(total != 5 * 1033){
345       printf(1, "pipe1 oops 3 total %d\n", total);
346       exit();
347     }
348     close(fds[0]);
349     wait();
350   } else {
351     printf(1, "fork() failed\n");
352     exit();
353   }
354   printf(1, "pipe1 ok\n");
355 }
356 
357 // meant to be run w/ at most two CPUs
358 void
preempt(void)359 preempt(void)
360 {
361   int pid1, pid2, pid3;
362   int pfds[2];
363 
364   printf(1, "preempt: ");
365   pid1 = fork();
366   if(pid1 == 0)
367     for(;;)
368       ;
369 
370   pid2 = fork();
371   if(pid2 == 0)
372     for(;;)
373       ;
374 
375   pipe(pfds);
376   pid3 = fork();
377   if(pid3 == 0){
378     close(pfds[0]);
379     if(write(pfds[1], "x", 1) != 1)
380       printf(1, "preempt write error");
381     close(pfds[1]);
382     for(;;)
383       ;
384   }
385 
386   close(pfds[1]);
387   if(read(pfds[0], buf, sizeof(buf)) != 1){
388     printf(1, "preempt read error");
389     return;
390   }
391   close(pfds[0]);
392   printf(1, "kill... ");
393   kill(pid1);
394   kill(pid2);
395   kill(pid3);
396   printf(1, "wait... ");
397   wait();
398   wait();
399   wait();
400   printf(1, "preempt ok\n");
401 }
402 
403 // try to find any races between exit and wait
404 void
exitwait(void)405 exitwait(void)
406 {
407   int i, pid;
408 
409   for(i = 0; i < 100; i++){
410     pid = fork();
411     if(pid < 0){
412       printf(1, "fork failed\n");
413       return;
414     }
415     if(pid){
416       if(wait() != pid){
417         printf(1, "wait wrong pid\n");
418         return;
419       }
420     } else {
421       exit();
422     }
423   }
424   printf(1, "exitwait ok\n");
425 }
426 
427 void
mem(void)428 mem(void)
429 {
430   void *m1, *m2;
431   int pid, ppid;
432 
433   printf(1, "mem test\n");
434   ppid = getpid();
435   if((pid = fork()) == 0){
436     m1 = 0;
437     while((m2 = malloc(10001)) != 0){
438       *(char**)m2 = m1;
439       m1 = m2;
440     }
441     while(m1){
442       m2 = *(char**)m1;
443       free(m1);
444       m1 = m2;
445     }
446     m1 = malloc(1024*20);
447     if(m1 == 0){
448       printf(1, "couldn't allocate mem?!!\n");
449       kill(ppid);
450       exit();
451     }
452     free(m1);
453     printf(1, "mem ok\n");
454     exit();
455   } else {
456     wait();
457   }
458 }
459 
460 // More file system tests
461 
462 // two processes write to the same file descriptor
463 // is the offset shared? does inode locking work?
464 void
sharedfd(void)465 sharedfd(void)
466 {
467   int fd, pid, i, n, nc, np;
468   char buf[10];
469 
470   printf(1, "sharedfd test\n");
471 
472   unlink("sharedfd");
473   fd = open("sharedfd", O_CREATE|O_RDWR);
474   if(fd < 0){
475     printf(1, "fstests: cannot open sharedfd for writing");
476     return;
477   }
478   pid = fork();
479   memset(buf, pid==0?'c':'p', sizeof(buf));
480   for(i = 0; i < 1000; i++){
481     if(write(fd, buf, sizeof(buf)) != sizeof(buf)){
482       printf(1, "fstests: write sharedfd failed\n");
483       break;
484     }
485   }
486   if(pid == 0)
487     exit();
488   else
489     wait();
490   close(fd);
491   fd = open("sharedfd", 0);
492   if(fd < 0){
493     printf(1, "fstests: cannot open sharedfd for reading\n");
494     return;
495   }
496   nc = np = 0;
497   while((n = read(fd, buf, sizeof(buf))) > 0){
498     for(i = 0; i < sizeof(buf); i++){
499       if(buf[i] == 'c')
500         nc++;
501       if(buf[i] == 'p')
502         np++;
503     }
504   }
505   close(fd);
506   unlink("sharedfd");
507   if(nc == 10000 && np == 10000){
508     printf(1, "sharedfd ok\n");
509   } else {
510     printf(1, "sharedfd oops %d %d\n", nc, np);
511     exit();
512   }
513 }
514 
515 // four processes write different files at the same
516 // time, to test block allocation.
517 void
fourfiles(void)518 fourfiles(void)
519 {
520   int fd, pid, i, j, n, total, pi;
521   char *names[] = { "f0", "f1", "f2", "f3" };
522   char *fname;
523 
524   printf(1, "fourfiles test\n");
525 
526   for(pi = 0; pi < 4; pi++){
527     fname = names[pi];
528     unlink(fname);
529 
530     pid = fork();
531     if(pid < 0){
532       printf(1, "fork failed\n");
533       exit();
534     }
535 
536     if(pid == 0){
537       fd = open(fname, O_CREATE | O_RDWR);
538       if(fd < 0){
539         printf(1, "create failed\n");
540         exit();
541       }
542 
543       memset(buf, '0'+pi, 512);
544       for(i = 0; i < 12; i++){
545         if((n = write(fd, buf, 500)) != 500){
546           printf(1, "write failed %d\n", n);
547           exit();
548         }
549       }
550       exit();
551     }
552   }
553 
554   for(pi = 0; pi < 4; pi++){
555     wait();
556   }
557 
558   for(i = 0; i < 2; i++){
559     fname = names[i];
560     fd = open(fname, 0);
561     total = 0;
562     while((n = read(fd, buf, sizeof(buf))) > 0){
563       for(j = 0; j < n; j++){
564         if(buf[j] != '0'+i){
565           printf(1, "wrong char\n");
566           exit();
567         }
568       }
569       total += n;
570     }
571     close(fd);
572     if(total != 12*500){
573       printf(1, "wrong length %d\n", total);
574       exit();
575     }
576     unlink(fname);
577   }
578 
579   printf(1, "fourfiles ok\n");
580 }
581 
582 // four processes create and delete different files in same directory
583 void
createdelete(void)584 createdelete(void)
585 {
586   enum { N = 20 };
587   int pid, i, fd, pi;
588   char name[32];
589 
590   printf(1, "createdelete test\n");
591 
592   for(pi = 0; pi < 4; pi++){
593     pid = fork();
594     if(pid < 0){
595       printf(1, "fork failed\n");
596       exit();
597     }
598 
599     if(pid == 0){
600       name[0] = 'p' + pi;
601       name[2] = '\0';
602       for(i = 0; i < N; i++){
603         name[1] = '0' + i;
604         fd = open(name, O_CREATE | O_RDWR);
605         if(fd < 0){
606           printf(1, "create failed\n");
607           exit();
608         }
609         close(fd);
610         if(i > 0 && (i % 2 ) == 0){
611           name[1] = '0' + (i / 2);
612           if(unlink(name) < 0){
613             printf(1, "unlink failed\n");
614             exit();
615           }
616         }
617       }
618       exit();
619     }
620   }
621 
622   for(pi = 0; pi < 4; pi++){
623     wait();
624   }
625 
626   name[0] = name[1] = name[2] = 0;
627   for(i = 0; i < N; i++){
628     for(pi = 0; pi < 4; pi++){
629       name[0] = 'p' + pi;
630       name[1] = '0' + i;
631       fd = open(name, 0);
632       if((i == 0 || i >= N/2) && fd < 0){
633         printf(1, "oops createdelete %s didn't exist\n", name);
634         exit();
635       } else if((i >= 1 && i < N/2) && fd >= 0){
636         printf(1, "oops createdelete %s did exist\n", name);
637         exit();
638       }
639       if(fd >= 0)
640         close(fd);
641     }
642   }
643 
644   for(i = 0; i < N; i++){
645     for(pi = 0; pi < 4; pi++){
646       name[0] = 'p' + i;
647       name[1] = '0' + i;
648       unlink(name);
649     }
650   }
651 
652   printf(1, "createdelete ok\n");
653 }
654 
655 // can I unlink a file and still read it?
656 void
unlinkread(void)657 unlinkread(void)
658 {
659   int fd, fd1;
660 
661   printf(1, "unlinkread test\n");
662   fd = open("unlinkread", O_CREATE | O_RDWR);
663   if(fd < 0){
664     printf(1, "create unlinkread failed\n");
665     exit();
666   }
667   write(fd, "hello", 5);
668   close(fd);
669 
670   fd = open("unlinkread", O_RDWR);
671   if(fd < 0){
672     printf(1, "open unlinkread failed\n");
673     exit();
674   }
675   if(unlink("unlinkread") != 0){
676     printf(1, "unlink unlinkread failed\n");
677     exit();
678   }
679 
680   fd1 = open("unlinkread", O_CREATE | O_RDWR);
681   write(fd1, "yyy", 3);
682   close(fd1);
683 
684   if(read(fd, buf, sizeof(buf)) != 5){
685     printf(1, "unlinkread read failed");
686     exit();
687   }
688   if(buf[0] != 'h'){
689     printf(1, "unlinkread wrong data\n");
690     exit();
691   }
692   if(write(fd, buf, 10) != 10){
693     printf(1, "unlinkread write failed\n");
694     exit();
695   }
696   close(fd);
697   unlink("unlinkread");
698   printf(1, "unlinkread ok\n");
699 }
700 
701 void
linktest(void)702 linktest(void)
703 {
704   int fd;
705 
706   printf(1, "linktest\n");
707 
708   unlink("lf1");
709   unlink("lf2");
710 
711   fd = open("lf1", O_CREATE|O_RDWR);
712   if(fd < 0){
713     printf(1, "create lf1 failed\n");
714     exit();
715   }
716   if(write(fd, "hello", 5) != 5){
717     printf(1, "write lf1 failed\n");
718     exit();
719   }
720   close(fd);
721 
722   if(link("lf1", "lf2") < 0){
723     printf(1, "link lf1 lf2 failed\n");
724     exit();
725   }
726   unlink("lf1");
727 
728   if(open("lf1", 0) >= 0){
729     printf(1, "unlinked lf1 but it is still there!\n");
730     exit();
731   }
732 
733   fd = open("lf2", 0);
734   if(fd < 0){
735     printf(1, "open lf2 failed\n");
736     exit();
737   }
738   if(read(fd, buf, sizeof(buf)) != 5){
739     printf(1, "read lf2 failed\n");
740     exit();
741   }
742   close(fd);
743 
744   if(link("lf2", "lf2") >= 0){
745     printf(1, "link lf2 lf2 succeeded! oops\n");
746     exit();
747   }
748 
749   unlink("lf2");
750   if(link("lf2", "lf1") >= 0){
751     printf(1, "link non-existant succeeded! oops\n");
752     exit();
753   }
754 
755   if(link(".", "lf1") >= 0){
756     printf(1, "link . lf1 succeeded! oops\n");
757     exit();
758   }
759 
760   printf(1, "linktest ok\n");
761 }
762 
763 // test concurrent create/link/unlink of the same file
764 void
concreate(void)765 concreate(void)
766 {
767   char file[3];
768   int i, pid, n, fd;
769   char fa[40];
770   struct {
771     ushort inum;
772     char name[14];
773   } de;
774 
775   printf(1, "concreate test\n");
776   file[0] = 'C';
777   file[2] = '\0';
778   for(i = 0; i < 40; i++){
779     file[1] = '0' + i;
780     unlink(file);
781     pid = fork();
782     if(pid && (i % 3) == 1){
783       link("C0", file);
784     } else if(pid == 0 && (i % 5) == 1){
785       link("C0", file);
786     } else {
787       fd = open(file, O_CREATE | O_RDWR);
788       if(fd < 0){
789         printf(1, "concreate create %s failed\n", file);
790         exit();
791       }
792       close(fd);
793     }
794     if(pid == 0)
795       exit();
796     else
797       wait();
798   }
799 
800   memset(fa, 0, sizeof(fa));
801   fd = open(".", 0);
802   n = 0;
803   while(read(fd, &de, sizeof(de)) > 0){
804     if(de.inum == 0)
805       continue;
806     if(de.name[0] == 'C' && de.name[2] == '\0'){
807       i = de.name[1] - '0';
808       if(i < 0 || i >= sizeof(fa)){
809         printf(1, "concreate weird file %s\n", de.name);
810         exit();
811       }
812       if(fa[i]){
813         printf(1, "concreate duplicate file %s\n", de.name);
814         exit();
815       }
816       fa[i] = 1;
817       n++;
818     }
819   }
820   close(fd);
821 
822   if(n != 40){
823     printf(1, "concreate not enough files in directory listing\n");
824     exit();
825   }
826 
827   for(i = 0; i < 40; i++){
828     file[1] = '0' + i;
829     pid = fork();
830     if(pid < 0){
831       printf(1, "fork failed\n");
832       exit();
833     }
834     if(((i % 3) == 0 && pid == 0) ||
835        ((i % 3) == 1 && pid != 0)){
836       close(open(file, 0));
837       close(open(file, 0));
838       close(open(file, 0));
839       close(open(file, 0));
840     } else {
841       unlink(file);
842       unlink(file);
843       unlink(file);
844       unlink(file);
845     }
846     if(pid == 0)
847       exit();
848     else
849       wait();
850   }
851 
852   printf(1, "concreate ok\n");
853 }
854 
855 // another concurrent link/unlink/create test,
856 // to look for deadlocks.
857 void
linkunlink()858 linkunlink()
859 {
860   int pid, i;
861 
862   printf(1, "linkunlink test\n");
863 
864   unlink("x");
865   pid = fork();
866   if(pid < 0){
867     printf(1, "fork failed\n");
868     exit();
869   }
870 
871   unsigned int x = (pid ? 1 : 97);
872   for(i = 0; i < 100; i++){
873     x = x * 1103515245 + 12345;
874     if((x % 3) == 0){
875       close(open("x", O_RDWR | O_CREATE));
876     } else if((x % 3) == 1){
877       link("cat", "x");
878     } else {
879       unlink("x");
880     }
881   }
882 
883   if(pid)
884     wait();
885   else
886     exit();
887 
888   printf(1, "linkunlink ok\n");
889 }
890 
891 // directory that uses indirect blocks
892 void
bigdir(void)893 bigdir(void)
894 {
895   int i, fd;
896   char name[10];
897 
898   printf(1, "bigdir test\n");
899   unlink("bd");
900 
901   fd = open("bd", O_CREATE);
902   if(fd < 0){
903     printf(1, "bigdir create failed\n");
904     exit();
905   }
906   close(fd);
907 
908   for(i = 0; i < 500; i++){
909     name[0] = 'x';
910     name[1] = '0' + (i / 64);
911     name[2] = '0' + (i % 64);
912     name[3] = '\0';
913     if(link("bd", name) != 0){
914       printf(1, "bigdir link failed\n");
915       exit();
916     }
917   }
918 
919   unlink("bd");
920   for(i = 0; i < 500; i++){
921     name[0] = 'x';
922     name[1] = '0' + (i / 64);
923     name[2] = '0' + (i % 64);
924     name[3] = '\0';
925     if(unlink(name) != 0){
926       printf(1, "bigdir unlink failed");
927       exit();
928     }
929   }
930 
931   printf(1, "bigdir ok\n");
932 }
933 
934 void
subdir(void)935 subdir(void)
936 {
937   int fd, cc;
938 
939   printf(1, "subdir test\n");
940 
941   unlink("ff");
942   if(mkdir("dd") != 0){
943     printf(1, "subdir mkdir dd failed\n");
944     exit();
945   }
946 
947   fd = open("dd/ff", O_CREATE | O_RDWR);
948   if(fd < 0){
949     printf(1, "create dd/ff failed\n");
950     exit();
951   }
952   write(fd, "ff", 2);
953   close(fd);
954 
955   if(unlink("dd") >= 0){
956     printf(1, "unlink dd (non-empty dir) succeeded!\n");
957     exit();
958   }
959 
960   if(mkdir("/dd/dd") != 0){
961     printf(1, "subdir mkdir dd/dd failed\n");
962     exit();
963   }
964 
965   fd = open("dd/dd/ff", O_CREATE | O_RDWR);
966   if(fd < 0){
967     printf(1, "create dd/dd/ff failed\n");
968     exit();
969   }
970   write(fd, "FF", 2);
971   close(fd);
972 
973   fd = open("dd/dd/../ff", 0);
974   if(fd < 0){
975     printf(1, "open dd/dd/../ff failed\n");
976     exit();
977   }
978   cc = read(fd, buf, sizeof(buf));
979   if(cc != 2 || buf[0] != 'f'){
980     printf(1, "dd/dd/../ff wrong content\n");
981     exit();
982   }
983   close(fd);
984 
985   if(link("dd/dd/ff", "dd/dd/ffff") != 0){
986     printf(1, "link dd/dd/ff dd/dd/ffff failed\n");
987     exit();
988   }
989 
990   if(unlink("dd/dd/ff") != 0){
991     printf(1, "unlink dd/dd/ff failed\n");
992     exit();
993   }
994   if(open("dd/dd/ff", O_RDONLY) >= 0){
995     printf(1, "open (unlinked) dd/dd/ff succeeded\n");
996     exit();
997   }
998 
999   if(chdir("dd") != 0){
1000     printf(1, "chdir dd failed\n");
1001     exit();
1002   }
1003   if(chdir("dd/../../dd") != 0){
1004     printf(1, "chdir dd/../../dd failed\n");
1005     exit();
1006   }
1007   if(chdir("dd/../../../dd") != 0){
1008     printf(1, "chdir dd/../../dd failed\n");
1009     exit();
1010   }
1011   if(chdir("./..") != 0){
1012     printf(1, "chdir ./.. failed\n");
1013     exit();
1014   }
1015 
1016   fd = open("dd/dd/ffff", 0);
1017   if(fd < 0){
1018     printf(1, "open dd/dd/ffff failed\n");
1019     exit();
1020   }
1021   if(read(fd, buf, sizeof(buf)) != 2){
1022     printf(1, "read dd/dd/ffff wrong len\n");
1023     exit();
1024   }
1025   close(fd);
1026 
1027   if(open("dd/dd/ff", O_RDONLY) >= 0){
1028     printf(1, "open (unlinked) dd/dd/ff succeeded!\n");
1029     exit();
1030   }
1031 
1032   if(open("dd/ff/ff", O_CREATE|O_RDWR) >= 0){
1033     printf(1, "create dd/ff/ff succeeded!\n");
1034     exit();
1035   }
1036   if(open("dd/xx/ff", O_CREATE|O_RDWR) >= 0){
1037     printf(1, "create dd/xx/ff succeeded!\n");
1038     exit();
1039   }
1040   if(open("dd", O_CREATE) >= 0){
1041     printf(1, "create dd succeeded!\n");
1042     exit();
1043   }
1044   if(open("dd", O_RDWR) >= 0){
1045     printf(1, "open dd rdwr succeeded!\n");
1046     exit();
1047   }
1048   if(open("dd", O_WRONLY) >= 0){
1049     printf(1, "open dd wronly succeeded!\n");
1050     exit();
1051   }
1052   if(link("dd/ff/ff", "dd/dd/xx") == 0){
1053     printf(1, "link dd/ff/ff dd/dd/xx succeeded!\n");
1054     exit();
1055   }
1056   if(link("dd/xx/ff", "dd/dd/xx") == 0){
1057     printf(1, "link dd/xx/ff dd/dd/xx succeeded!\n");
1058     exit();
1059   }
1060   if(link("dd/ff", "dd/dd/ffff") == 0){
1061     printf(1, "link dd/ff dd/dd/ffff succeeded!\n");
1062     exit();
1063   }
1064   if(mkdir("dd/ff/ff") == 0){
1065     printf(1, "mkdir dd/ff/ff succeeded!\n");
1066     exit();
1067   }
1068   if(mkdir("dd/xx/ff") == 0){
1069     printf(1, "mkdir dd/xx/ff succeeded!\n");
1070     exit();
1071   }
1072   if(mkdir("dd/dd/ffff") == 0){
1073     printf(1, "mkdir dd/dd/ffff succeeded!\n");
1074     exit();
1075   }
1076   if(unlink("dd/xx/ff") == 0){
1077     printf(1, "unlink dd/xx/ff succeeded!\n");
1078     exit();
1079   }
1080   if(unlink("dd/ff/ff") == 0){
1081     printf(1, "unlink dd/ff/ff succeeded!\n");
1082     exit();
1083   }
1084   if(chdir("dd/ff") == 0){
1085     printf(1, "chdir dd/ff succeeded!\n");
1086     exit();
1087   }
1088   if(chdir("dd/xx") == 0){
1089     printf(1, "chdir dd/xx succeeded!\n");
1090     exit();
1091   }
1092 
1093   if(unlink("dd/dd/ffff") != 0){
1094     printf(1, "unlink dd/dd/ff failed\n");
1095     exit();
1096   }
1097   if(unlink("dd/ff") != 0){
1098     printf(1, "unlink dd/ff failed\n");
1099     exit();
1100   }
1101   if(unlink("dd") == 0){
1102     printf(1, "unlink non-empty dd succeeded!\n");
1103     exit();
1104   }
1105   if(unlink("dd/dd") < 0){
1106     printf(1, "unlink dd/dd failed\n");
1107     exit();
1108   }
1109   if(unlink("dd") < 0){
1110     printf(1, "unlink dd failed\n");
1111     exit();
1112   }
1113 
1114   printf(1, "subdir ok\n");
1115 }
1116 
1117 // test writes that are larger than the log.
1118 void
bigwrite(void)1119 bigwrite(void)
1120 {
1121   int fd, sz;
1122 
1123   printf(1, "bigwrite test\n");
1124 
1125   unlink("bigwrite");
1126   for(sz = 499; sz < 12*512; sz += 471){
1127     fd = open("bigwrite", O_CREATE | O_RDWR);
1128     if(fd < 0){
1129       printf(1, "cannot create bigwrite\n");
1130       exit();
1131     }
1132     int i;
1133     for(i = 0; i < 2; i++){
1134       int cc = write(fd, buf, sz);
1135       if(cc != sz){
1136         printf(1, "write(%d) ret %d\n", sz, cc);
1137         exit();
1138       }
1139     }
1140     close(fd);
1141     unlink("bigwrite");
1142   }
1143 
1144   printf(1, "bigwrite ok\n");
1145 }
1146 
1147 void
bigfile(void)1148 bigfile(void)
1149 {
1150   int fd, i, total, cc;
1151 
1152   printf(1, "bigfile test\n");
1153 
1154   unlink("bigfile");
1155   fd = open("bigfile", O_CREATE | O_RDWR);
1156   if(fd < 0){
1157     printf(1, "cannot create bigfile");
1158     exit();
1159   }
1160   for(i = 0; i < 20; i++){
1161     memset(buf, i, 600);
1162     if(write(fd, buf, 600) != 600){
1163       printf(1, "write bigfile failed\n");
1164       exit();
1165     }
1166   }
1167   close(fd);
1168 
1169   fd = open("bigfile", 0);
1170   if(fd < 0){
1171     printf(1, "cannot open bigfile\n");
1172     exit();
1173   }
1174   total = 0;
1175   for(i = 0; ; i++){
1176     cc = read(fd, buf, 300);
1177     if(cc < 0){
1178       printf(1, "read bigfile failed\n");
1179       exit();
1180     }
1181     if(cc == 0)
1182       break;
1183     if(cc != 300){
1184       printf(1, "short read bigfile\n");
1185       exit();
1186     }
1187     if(buf[0] != i/2 || buf[299] != i/2){
1188       printf(1, "read bigfile wrong data\n");
1189       exit();
1190     }
1191     total += cc;
1192   }
1193   close(fd);
1194   if(total != 20*600){
1195     printf(1, "read bigfile wrong total\n");
1196     exit();
1197   }
1198   unlink("bigfile");
1199 
1200   printf(1, "bigfile test ok\n");
1201 }
1202 
1203 void
fourteen(void)1204 fourteen(void)
1205 {
1206   int fd;
1207 
1208   // DIRSIZ is 14.
1209   printf(1, "fourteen test\n");
1210 
1211   if(mkdir("12345678901234") != 0){
1212     printf(1, "mkdir 12345678901234 failed\n");
1213     exit();
1214   }
1215   if(mkdir("12345678901234/123456789012345") != 0){
1216     printf(1, "mkdir 12345678901234/123456789012345 failed\n");
1217     exit();
1218   }
1219   fd = open("123456789012345/123456789012345/123456789012345", O_CREATE);
1220   if(fd < 0){
1221     printf(1, "create 123456789012345/123456789012345/123456789012345 failed\n");
1222     exit();
1223   }
1224   close(fd);
1225   fd = open("12345678901234/12345678901234/12345678901234", 0);
1226   if(fd < 0){
1227     printf(1, "open 12345678901234/12345678901234/12345678901234 failed\n");
1228     exit();
1229   }
1230   close(fd);
1231 
1232   if(mkdir("12345678901234/12345678901234") == 0){
1233     printf(1, "mkdir 12345678901234/12345678901234 succeeded!\n");
1234     exit();
1235   }
1236   if(mkdir("123456789012345/12345678901234") == 0){
1237     printf(1, "mkdir 12345678901234/123456789012345 succeeded!\n");
1238     exit();
1239   }
1240 
1241   printf(1, "fourteen ok\n");
1242 }
1243 
1244 void
rmdot(void)1245 rmdot(void)
1246 {
1247   printf(1, "rmdot test\n");
1248   if(mkdir("dots") != 0){
1249     printf(1, "mkdir dots failed\n");
1250     exit();
1251   }
1252   if(chdir("dots") != 0){
1253     printf(1, "chdir dots failed\n");
1254     exit();
1255   }
1256   if(unlink(".") == 0){
1257     printf(1, "rm . worked!\n");
1258     exit();
1259   }
1260   if(unlink("..") == 0){
1261     printf(1, "rm .. worked!\n");
1262     exit();
1263   }
1264   if(chdir("/") != 0){
1265     printf(1, "chdir / failed\n");
1266     exit();
1267   }
1268   if(unlink("dots/.") == 0){
1269     printf(1, "unlink dots/. worked!\n");
1270     exit();
1271   }
1272   if(unlink("dots/..") == 0){
1273     printf(1, "unlink dots/.. worked!\n");
1274     exit();
1275   }
1276   if(unlink("dots") != 0){
1277     printf(1, "unlink dots failed!\n");
1278     exit();
1279   }
1280   printf(1, "rmdot ok\n");
1281 }
1282 
1283 void
dirfile(void)1284 dirfile(void)
1285 {
1286   int fd;
1287 
1288   printf(1, "dir vs file\n");
1289 
1290   fd = open("dirfile", O_CREATE);
1291   if(fd < 0){
1292     printf(1, "create dirfile failed\n");
1293     exit();
1294   }
1295   close(fd);
1296   if(chdir("dirfile") == 0){
1297     printf(1, "chdir dirfile succeeded!\n");
1298     exit();
1299   }
1300   fd = open("dirfile/xx", 0);
1301   if(fd >= 0){
1302     printf(1, "create dirfile/xx succeeded!\n");
1303     exit();
1304   }
1305   fd = open("dirfile/xx", O_CREATE);
1306   if(fd >= 0){
1307     printf(1, "create dirfile/xx succeeded!\n");
1308     exit();
1309   }
1310   if(mkdir("dirfile/xx") == 0){
1311     printf(1, "mkdir dirfile/xx succeeded!\n");
1312     exit();
1313   }
1314   if(unlink("dirfile/xx") == 0){
1315     printf(1, "unlink dirfile/xx succeeded!\n");
1316     exit();
1317   }
1318   if(link("README", "dirfile/xx") == 0){
1319     printf(1, "link to dirfile/xx succeeded!\n");
1320     exit();
1321   }
1322   if(unlink("dirfile") != 0){
1323     printf(1, "unlink dirfile failed!\n");
1324     exit();
1325   }
1326 
1327   fd = open(".", O_RDWR);
1328   if(fd >= 0){
1329     printf(1, "open . for writing succeeded!\n");
1330     exit();
1331   }
1332   fd = open(".", 0);
1333   if(write(fd, "x", 1) > 0){
1334     printf(1, "write . succeeded!\n");
1335     exit();
1336   }
1337   close(fd);
1338 
1339   printf(1, "dir vs file OK\n");
1340 }
1341 
1342 // test that iput() is called at the end of _namei()
1343 void
iref(void)1344 iref(void)
1345 {
1346   int i, fd;
1347 
1348   printf(1, "empty file name\n");
1349 
1350   // the 50 is NINODE
1351   for(i = 0; i < 50 + 1; i++){
1352     if(mkdir("irefd") != 0){
1353       printf(1, "mkdir irefd failed\n");
1354       exit();
1355     }
1356     if(chdir("irefd") != 0){
1357       printf(1, "chdir irefd failed\n");
1358       exit();
1359     }
1360 
1361     mkdir("");
1362     link("README", "");
1363     fd = open("", O_CREATE);
1364     if(fd >= 0)
1365       close(fd);
1366     fd = open("xx", O_CREATE);
1367     if(fd >= 0)
1368       close(fd);
1369     unlink("xx");
1370   }
1371 
1372   chdir("/");
1373   printf(1, "empty file name OK\n");
1374 }
1375 
1376 // test that fork fails gracefully
1377 // the forktest binary also does this, but it runs out of proc entries first.
1378 // inside the bigger usertests binary, we run out of memory first.
1379 void
forktest(void)1380 forktest(void)
1381 {
1382   int n, pid;
1383 
1384   printf(1, "fork test\n");
1385 
1386   for(n=0; n<1000; n++){
1387     pid = fork();
1388     if(pid < 0)
1389       break;
1390     if(pid == 0)
1391       exit();
1392   }
1393 
1394   if(n == 1000){
1395     printf(1, "fork claimed to work 1000 times!\n");
1396     exit();
1397   }
1398 
1399   for(; n > 0; n--){
1400     if(wait() < 0){
1401       printf(1, "wait stopped early\n");
1402       exit();
1403     }
1404   }
1405 
1406   if(wait() != -1){
1407     printf(1, "wait got too many\n");
1408     exit();
1409   }
1410 
1411   printf(1, "fork test OK\n");
1412 }
1413 
1414 void
sbrktest(void)1415 sbrktest(void)
1416 {
1417   int fds[2], pid, pids[10], ppid;
1418   char *a, *b, *c, *lastaddr, *oldbrk, *p, scratch;
1419   uint amt;
1420 
1421   printf(stdout, "sbrk test\n");
1422   oldbrk = sbrk(0);
1423 
1424   // can one sbrk() less than a page?
1425   a = sbrk(0);
1426   int i;
1427   for(i = 0; i < 5000; i++){
1428     b = sbrk(1);
1429     if(b != a){
1430       printf(stdout, "sbrk test failed %d %x %x\n", i, a, b);
1431       exit();
1432     }
1433     *b = 1;
1434     a = b + 1;
1435   }
1436   pid = fork();
1437   if(pid < 0){
1438     printf(stdout, "sbrk test fork failed\n");
1439     exit();
1440   }
1441   c = sbrk(1);
1442   c = sbrk(1);
1443   if(c != a + 1){
1444     printf(stdout, "sbrk test failed post-fork\n");
1445     exit();
1446   }
1447   if(pid == 0)
1448     exit();
1449   wait();
1450 
1451   // can one grow address space to something big?
1452 #define BIG (100*1024*1024)
1453   a = sbrk(0);
1454   amt = (BIG) - (uint)a;
1455   p = sbrk(amt);
1456   if (p != a) {
1457     printf(stdout, "sbrk test failed to grow big address space; enough phys mem?\n");
1458     exit();
1459   }
1460   lastaddr = (char*) (BIG-1);
1461   *lastaddr = 99;
1462 
1463   // can one de-allocate?
1464   a = sbrk(0);
1465   c = sbrk(-4096);
1466   if(c == (char*)0xffffffff){
1467     printf(stdout, "sbrk could not deallocate\n");
1468     exit();
1469   }
1470   c = sbrk(0);
1471   if(c != a - 4096){
1472     printf(stdout, "sbrk deallocation produced wrong address, a %x c %x\n", a, c);
1473     exit();
1474   }
1475 
1476   // can one re-allocate that page?
1477   a = sbrk(0);
1478   c = sbrk(4096);
1479   if(c != a || sbrk(0) != a + 4096){
1480     printf(stdout, "sbrk re-allocation failed, a %x c %x\n", a, c);
1481     exit();
1482   }
1483   if(*lastaddr == 99){
1484     // should be zero
1485     printf(stdout, "sbrk de-allocation didn't really deallocate\n");
1486     exit();
1487   }
1488 
1489   a = sbrk(0);
1490   c = sbrk(-(sbrk(0) - oldbrk));
1491   if(c != a){
1492     printf(stdout, "sbrk downsize failed, a %x c %x\n", a, c);
1493     exit();
1494   }
1495 
1496   // can we read the kernel's memory?
1497   for(a = (char*)(KERNBASE); a < (char*) (KERNBASE+2000000); a += 50000){
1498     ppid = getpid();
1499     pid = fork();
1500     if(pid < 0){
1501       printf(stdout, "fork failed\n");
1502       exit();
1503     }
1504     if(pid == 0){
1505       printf(stdout, "oops could read %x = %x\n", a, *a);
1506       kill(ppid);
1507       exit();
1508     }
1509     wait();
1510   }
1511 
1512   // if we run the system out of memory, does it clean up the last
1513   // failed allocation?
1514   if(pipe(fds) != 0){
1515     printf(1, "pipe() failed\n");
1516     exit();
1517   }
1518   for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
1519     if((pids[i] = fork()) == 0){
1520       // allocate a lot of memory
1521       sbrk(BIG - (uint)sbrk(0));
1522       write(fds[1], "x", 1);
1523       // sit around until killed
1524       for(;;) sleep(1000);
1525     }
1526     if(pids[i] != -1)
1527       read(fds[0], &scratch, 1);
1528   }
1529   // if those failed allocations freed up the pages they did allocate,
1530   // we'll be able to allocate here
1531   c = sbrk(4096);
1532   for(i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
1533     if(pids[i] == -1)
1534       continue;
1535     kill(pids[i]);
1536     wait();
1537   }
1538   if(c == (char*)0xffffffff){
1539     printf(stdout, "failed sbrk leaked memory\n");
1540     exit();
1541   }
1542 
1543   if(sbrk(0) > oldbrk)
1544     sbrk(-(sbrk(0) - oldbrk));
1545 
1546   printf(stdout, "sbrk test OK\n");
1547 }
1548 
1549 void
validateint(int * p)1550 validateint(int *p)
1551 {
1552   int res;
1553   asm("mov %%esp, %%ebx\n\t"
1554       "mov %3, %%esp\n\t"
1555       "int %2\n\t"
1556       "mov %%ebx, %%esp" :
1557       "=a" (res) :
1558       "a" (SYS_sleep), "n" (T_SYSCALL), "c" (p) :
1559       "ebx");
1560 }
1561 
1562 void
validatetest(void)1563 validatetest(void)
1564 {
1565   int hi, pid;
1566   uint p;
1567 
1568   printf(stdout, "validate test\n");
1569   hi = 1100*1024;
1570 
1571   for(p = 0; p <= (uint)hi; p += 4096){
1572     if((pid = fork()) == 0){
1573       // try to crash the kernel by passing in a badly placed integer
1574       validateint((int*)p);
1575       exit();
1576     }
1577     sleep(0);
1578     sleep(0);
1579     kill(pid);
1580     wait();
1581 
1582     // try to crash the kernel by passing in a bad string pointer
1583     if(link("nosuchfile", (char*)p) != -1){
1584       printf(stdout, "link should not succeed\n");
1585       exit();
1586     }
1587   }
1588 
1589   printf(stdout, "validate ok\n");
1590 }
1591 
1592 // does unintialized data start out zero?
1593 char uninit[10000];
1594 void
bsstest(void)1595 bsstest(void)
1596 {
1597   int i;
1598 
1599   printf(stdout, "bss test\n");
1600   for(i = 0; i < sizeof(uninit); i++){
1601     if(uninit[i] != '\0'){
1602       printf(stdout, "bss test failed\n");
1603       exit();
1604     }
1605   }
1606   printf(stdout, "bss test ok\n");
1607 }
1608 
1609 // does exec return an error if the arguments
1610 // are larger than a page? or does it write
1611 // below the stack and wreck the instructions/data?
1612 void
bigargtest(void)1613 bigargtest(void)
1614 {
1615   int pid, fd;
1616 
1617   unlink("bigarg-ok");
1618   pid = fork();
1619   if(pid == 0){
1620     static char *args[MAXARG];
1621     int i;
1622     for(i = 0; i < MAXARG-1; i++)
1623       args[i] = "bigargs test: failed\n                                                                                                                                                                                                       ";
1624     args[MAXARG-1] = 0;
1625     printf(stdout, "bigarg test\n");
1626     exec("echo", args);
1627     printf(stdout, "bigarg test ok\n");
1628     fd = open("bigarg-ok", O_CREATE);
1629     close(fd);
1630     exit();
1631   } else if(pid < 0){
1632     printf(stdout, "bigargtest: fork failed\n");
1633     exit();
1634   }
1635   wait();
1636   fd = open("bigarg-ok", 0);
1637   if(fd < 0){
1638     printf(stdout, "bigarg test failed!\n");
1639     exit();
1640   }
1641   close(fd);
1642   unlink("bigarg-ok");
1643 }
1644 
1645 // what happens when the file system runs out of blocks?
1646 // answer: balloc panics, so this test is not useful.
1647 void
fsfull()1648 fsfull()
1649 {
1650   int nfiles;
1651   int fsblocks = 0;
1652 
1653   printf(1, "fsfull test\n");
1654 
1655   for(nfiles = 0; ; nfiles++){
1656     char name[64];
1657     name[0] = 'f';
1658     name[1] = '0' + nfiles / 1000;
1659     name[2] = '0' + (nfiles % 1000) / 100;
1660     name[3] = '0' + (nfiles % 100) / 10;
1661     name[4] = '0' + (nfiles % 10);
1662     name[5] = '\0';
1663     printf(1, "writing %s\n", name);
1664     int fd = open(name, O_CREATE|O_RDWR);
1665     if(fd < 0){
1666       printf(1, "open %s failed\n", name);
1667       break;
1668     }
1669     int total = 0;
1670     while(1){
1671       int cc = write(fd, buf, 512);
1672       if(cc < 512)
1673         break;
1674       total += cc;
1675       fsblocks++;
1676     }
1677     printf(1, "wrote %d bytes\n", total);
1678     close(fd);
1679     if(total == 0)
1680       break;
1681   }
1682 
1683   while(nfiles >= 0){
1684     char name[64];
1685     name[0] = 'f';
1686     name[1] = '0' + nfiles / 1000;
1687     name[2] = '0' + (nfiles % 1000) / 100;
1688     name[3] = '0' + (nfiles % 100) / 10;
1689     name[4] = '0' + (nfiles % 10);
1690     name[5] = '\0';
1691     unlink(name);
1692     nfiles--;
1693   }
1694 
1695   printf(1, "fsfull test finished\n");
1696 }
1697 
1698 void
uio()1699 uio()
1700 {
1701   #define RTC_ADDR 0x70
1702   #define RTC_DATA 0x71
1703 
1704   ushort port = 0;
1705   uchar val = 0;
1706   int pid;
1707 
1708   printf(1, "uio test\n");
1709   pid = fork();
1710   if(pid == 0){
1711     port = RTC_ADDR;
1712     val = 0x09;  /* year */
1713     /* http://wiki.osdev.org/Inline_Assembly/Examples */
1714     asm volatile("outb %0,%1"::"a"(val), "d" (port));
1715     port = RTC_DATA;
1716     asm volatile("inb %1,%0" : "=a" (val) : "d" (port));
1717     printf(1, "uio: uio succeeded; test FAILED\n");
1718     exit();
1719   } else if(pid < 0){
1720     printf (1, "fork failed\n");
1721     exit();
1722   }
1723   wait();
1724   printf(1, "uio test done\n");
1725 }
1726 
argptest()1727 void argptest()
1728 {
1729   int fd;
1730   fd = open("init", O_RDONLY);
1731   if (fd < 0) {
1732     printf(2, "open failed\n");
1733     exit();
1734   }
1735   read(fd, sbrk(0) - 1, -1);
1736   close(fd);
1737   printf(1, "arg test passed\n");
1738 }
1739 
1740 unsigned long randstate = 1;
1741 unsigned int
rand()1742 rand()
1743 {
1744   randstate = randstate * 1664525 + 1013904223;
1745   return randstate;
1746 }
1747 
1748 int
main(int argc,char * argv[])1749 main(int argc, char *argv[])
1750 {
1751   printf(1, "usertests starting\n");
1752 
1753   if(open("usertests.ran", 0) >= 0){
1754     printf(1, "already ran user tests -- rebuild fs.img\n");
1755     exit();
1756   }
1757   close(open("usertests.ran", O_CREATE));
1758 
1759   argptest();
1760   createdelete();
1761   linkunlink();
1762   concreate();
1763   fourfiles();
1764   sharedfd();
1765 
1766   bigargtest();
1767   bigwrite();
1768   bigargtest();
1769   bsstest();
1770   sbrktest();
1771   validatetest();
1772 
1773   opentest();
1774   writetest();
1775   writetest1();
1776   createtest();
1777 
1778   openiputtest();
1779   exitiputtest();
1780   iputtest();
1781 
1782   mem();
1783   pipe1();
1784   preempt();
1785   exitwait();
1786 
1787   rmdot();
1788   fourteen();
1789   bigfile();
1790   subdir();
1791   linktest();
1792   unlinkread();
1793   dirfile();
1794   iref();
1795   forktest();
1796   bigdir(); // slow
1797 
1798   uio();
1799 
1800   exectest();
1801 
1802   exit();
1803 }
1804