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