diff options
| author | Robert Morris <rtm@csail.mit.edu> | 2019-11-07 09:46:20 -0500 | 
|---|---|---|
| committer | Frans Kaashoek <kaashoek@mit.edu> | 2020-08-10 11:19:10 -0400 | 
| commit | b62d4d412bf36eb445dd05cf80762ba8837de6ce (patch) | |
| tree | 9d6222e63eaac32f5e5a5c442ec553977021dcae /user | |
| parent | 897f6f34ddf2b45f7ef0e2474691f28cb6c9c0bd (diff) | |
| download | xv6-labs-b62d4d412bf36eb445dd05cf80762ba8837de6ce.tar.gz xv6-labs-b62d4d412bf36eb445dd05cf80762ba8837de6ce.tar.bz2 xv6-labs-b62d4d412bf36eb445dd05cf80762ba8837de6ce.zip | |
more grind
Diffstat (limited to 'user')
| -rw-r--r-- | user/cat.c | 8 | ||||
| -rw-r--r-- | user/grind.c | 155 | 
2 files changed, 145 insertions, 18 deletions
| @@ -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); +      }      }    }  } | 
