0
|
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 }
|