summaryrefslogtreecommitdiff
path: root/user
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-11-07 09:46:20 -0500
committerFrans Kaashoek <[email protected]>2020-08-10 11:19:10 -0400
commitb62d4d412bf36eb445dd05cf80762ba8837de6ce (patch)
tree9d6222e63eaac32f5e5a5c442ec553977021dcae /user
parent897f6f34ddf2b45f7ef0e2474691f28cb6c9c0bd (diff)
downloadxv6-labs-b62d4d412bf36eb445dd05cf80762ba8837de6ce.tar.gz
xv6-labs-b62d4d412bf36eb445dd05cf80762ba8837de6ce.tar.bz2
xv6-labs-b62d4d412bf36eb445dd05cf80762ba8837de6ce.zip
more grind
Diffstat (limited to 'user')
-rw-r--r--user/cat.c8
-rw-r--r--user/grind.c155
2 files changed, 145 insertions, 18 deletions
diff --git a/user/cat.c b/user/cat.c
index 36939d8..598f005 100644
--- a/user/cat.c
+++ b/user/cat.c
@@ -11,12 +11,12 @@ cat(int fd)
while((n = read(fd, buf, sizeof(buf))) > 0) {
if (write(1, buf, n) != n) {
- printf("cat: write error\n");
+ fprintf(2, "cat: write error\n");
exit(1);
}
}
if(n < 0){
- printf("cat: read error\n");
+ fprintf(2, "cat: read error\n");
exit(1);
}
}
@@ -28,12 +28,12 @@ main(int argc, char *argv[])
if(argc <= 1){
cat(0);
- exit(1);
+ exit(0);
}
for(i = 1; i < argc; i++){
if((fd = open(argv[i], 0)) < 0){
- printf("cat: cannot open %s\n", argv[i]);
+ fprintf(2, "cat: cannot open %s\n", argv[i]);
exit(1);
}
cat(fd);
diff --git a/user/grind.c b/user/grind.c
index a01271e..6203e57 100644
--- a/user/grind.c
+++ b/user/grind.c
@@ -54,44 +54,56 @@ go(int which_child)
static char buf[999];
char *break0 = sbrk(0);
uint64 iters = 0;
+
+ mkdir("grindir");
+ if(chdir("grindir") != 0){
+ printf("chdir grindir failed\n");
+ exit(1);
+ }
+ chdir("/");
while(1){
iters++;
if((iters % 500) == 0)
write(1, which_child?"B":"A", 1);
- int what = rand() % 20;
+ int what = rand() % 23;
if(what == 1){
- close(open("a", O_CREATE|O_RDWR));
+ close(open("grindir/../a", O_CREATE|O_RDWR));
} else if(what == 2){
- close(open("b", O_CREATE|O_RDWR));
+ close(open("grindir/../grindir/../b", O_CREATE|O_RDWR));
} else if(what == 3){
- unlink("a");
+ unlink("grindir/../a");
} else if(what == 4){
- unlink("b");
+ if(chdir("grindir") != 0){
+ printf("chdir grindir failed\n");
+ exit(1);
+ }
+ unlink("../b");
+ chdir("/");
} else if(what == 5){
close(fd);
- fd = open("a", O_CREATE|O_RDWR);
+ fd = open("/grindir/../a", O_CREATE|O_RDWR);
} else if(what == 6){
close(fd);
- fd = open("b", O_CREATE|O_RDWR);
+ fd = open("/./grindir/./../b", O_CREATE|O_RDWR);
} else if(what == 7){
write(fd, buf, sizeof(buf));
} else if(what == 8){
read(fd, buf, sizeof(buf));
} else if(what == 9){
- mkdir("a");
- close(open("a/a", O_CREATE|O_RDWR));
+ mkdir("grindir/../a");
+ close(open("a/../a/./a", O_CREATE|O_RDWR));
unlink("a/a");
} else if(what == 10){
- mkdir("b");
- close(open("b/b", O_CREATE|O_RDWR));
+ mkdir("/../b");
+ close(open("grindir/../b/b", O_CREATE|O_RDWR));
unlink("b/b");
} else if(what == 11){
unlink("b");
- link("a", "b");
+ link("../grindir/./../a", "../b");
} else if(what == 12){
- unlink("a");
- link("b", "a");
+ unlink("../grindir/../a");
+ link(".././b", "/grindir/../a");
} else if(what == 13){
int pid = fork();
if(pid == 0){
@@ -126,6 +138,10 @@ go(int which_child)
printf("grind: fork failed\n");
exit(1);
}
+ if(chdir("../grindir/..") != 0){
+ printf("chdir failed\n");
+ exit(1);
+ }
kill(pid);
wait(0);
} else if(what == 18){
@@ -161,6 +177,117 @@ go(int which_child)
close(fds[0]);
close(fds[1]);
wait(0);
+ } else if(what == 20){
+ int pid = fork();
+ if(pid == 0){
+ unlink("a");
+ mkdir("a");
+ chdir("a");
+ unlink("../a");
+ fd = open("x", O_CREATE|O_RDWR);
+ unlink("x");
+ exit(0);
+ } else if(pid < 0){
+ printf("fork failed\n");
+ exit(1);
+ }
+ wait(0);
+ } else if(what == 21){
+ unlink("c");
+ // should always succeed. check that there are free i-nodes,
+ // file descriptors, blocks.
+ int fd1 = open("c", O_CREATE|O_RDWR);
+ if(fd1 < 0){
+ printf("create c failed\n");
+ exit(1);
+ }
+ if(write(fd1, "x", 1) != 1){
+ printf("write c failed\n");
+ exit(1);
+ }
+ struct stat st;
+ if(fstat(fd1, &st) != 0){
+ printf("fstat failed\n");
+ exit(1);
+ }
+ if(st.size != 1){
+ printf("fstat reports wrong size %d\n", (int)st.size);
+ exit(1);
+ }
+ if(st.ino > 50){
+ printf("fstat reports crazy i-number %d\n", st.ino);
+ exit(1);
+ }
+ close(fd1);
+ unlink("c");
+ } else if(what == 22){
+ // echo hi | cat
+ int aa[2], bb[2];
+ if(pipe(aa) < 0){
+ fprintf(2, "pipe failed\n");
+ exit(1);
+ }
+ if(pipe(bb) < 0){
+ fprintf(2, "pipe failed\n");
+ exit(1);
+ }
+ int pid1 = fork();
+ if(pid1 == 0){
+ close(bb[0]);
+ close(bb[1]);
+ close(aa[0]);
+ close(1);
+ if(dup(aa[1]) != 1){
+ fprintf(2, "dup failed\n");
+ exit(1);
+ }
+ close(aa[1]);
+ char *args[3] = { "echo", "hi", 0 };
+ exec("grindir/../echo", args);
+ fprintf(2, "echo: not found\n");
+ exit(2);
+ } else if(pid1 < 0){
+ fprintf(2, "fork failed\n");
+ exit(3);
+ }
+ int pid2 = fork();
+ if(pid2 == 0){
+ close(aa[1]);
+ close(bb[0]);
+ close(0);
+ if(dup(aa[0]) != 0){
+ fprintf(2, "dup failed\n");
+ exit(4);
+ }
+ close(aa[0]);
+ close(1);
+ if(dup(bb[1]) != 1){
+ fprintf(2, "dup failed\n");
+ exit(5);
+ }
+ close(bb[1]);
+ char *args[2] = { "cat", 0 };
+ exec("/cat", args);
+ fprintf(2, "cat: not found\n");
+ exit(6);
+ } else if(pid2 < 0){
+ fprintf(2, "fork failed\n");
+ exit(7);
+ }
+ close(aa[0]);
+ close(aa[1]);
+ close(bb[1]);
+ char buf[3] = { 0, 0, 0 };
+ read(bb[0], buf+0, 1);
+ read(bb[0], buf+1, 1);
+ close(bb[0]);
+ int st1, st2;
+ wait(&st1);
+ wait(&st2);
+ if(st1 != 0 || st2 != 0 || strcmp(buf, "hi") != 0){
+ printf("exec pipeline failed %d %d \"%s\"\n", st1, st2, buf);
+ exit(1);
+ }
}
}
}