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