diff options
| -rw-r--r-- | Makefile | 20 | ||||
| -rw-r--r-- | fstests.c | 685 | ||||
| -rw-r--r-- | user1.c | 22 | ||||
| -rw-r--r-- | userfs.c | 210 | ||||
| -rw-r--r-- | usertests.c | 898 | 
5 files changed, 894 insertions, 941 deletions
| @@ -84,18 +84,10 @@ vectors.S : vectors.pl  ULIB = ulib.o usys.o printf.o umalloc.o -user1 : user1.o $(ULIB) -	$(LD) -N -e main -Ttext 0 -o user1 user1.o $(ULIB) -	$(OBJDUMP) -S user1 > user1.asm -  usertests : usertests.o $(ULIB)  	$(LD) -N -e main -Ttext 0 -o usertests usertests.o $(ULIB)  	$(OBJDUMP) -S usertests > usertests.asm -fstests : fstests.o $(ULIB) -	$(LD) -N -e main -Ttext 0 -o fstests fstests.o $(ULIB) -	$(OBJDUMP) -S fstests > fstests.asm -  _echo : echo.o $(ULIB)  	$(LD) -N -e main -Ttext 0 -o _echo echo.o $(ULIB)  	$(OBJDUMP) -S _echo > echo.asm @@ -104,10 +96,6 @@ _cat : cat.o $(ULIB)  	$(LD) -N -e main -Ttext 0 -o _cat cat.o $(ULIB)  	$(OBJDUMP) -S _cat > cat.asm -userfs : userfs.o $(ULIB) -	$(LD) -N -e main -Ttext 0 -o userfs userfs.o $(ULIB) -	$(OBJDUMP) -S userfs > userfs.asm -  _init : init.o $(ULIB)  	$(LD) -N -e main -Ttext 0 -o _init init.o $(ULIB)  	$(OBJDUMP) -S _init > init.asm @@ -131,8 +119,8 @@ _rm : rm.o $(ULIB)  mkfs : mkfs.c fs.h  	cc -o mkfs mkfs.c -fs.img : mkfs userfs usertests _echo _cat README _init _sh _ls _mkdir _rm fstests -	./mkfs fs.img userfs usertests _echo _cat README _init _sh _ls _mkdir _rm fstests +fs.img : mkfs usertests _echo _cat README _init _sh _ls _mkdir _rm fstests +	./mkfs fs.img usertests _echo _cat README _init _sh _ls _mkdir _rm fstests  -include *.d @@ -140,5 +128,5 @@ clean :  	/bin/rm -f rm  	rm -f *.ps *.tex *.dvi *.idx *.aux *.log *.ind *.ilg \  	*.o *.d *.asm vectors.S parport.out \ -	bootblock kernel xv6.img user1 userfs usertests \ -	fs.img mkfs echo init fstests +	bootblock kernel xv6.img usertests \ +	fs.img mkfs echo init diff --git a/fstests.c b/fstests.c deleted file mode 100644 index 4956437..0000000 --- a/fstests.c +++ /dev/null @@ -1,685 +0,0 @@ -#include "types.h" -#include "stat.h" -#include "user.h" -#include "fcntl.h" - -char buf[512]; - -// two processes write to the same file descriptor -// is the offset shared? does inode locking work? -void -sharedfd() -{ -  int fd, pid, i, n, nc, np; -  char buf[10]; - -  unlink("sharedfd"); -  fd = open("sharedfd", O_CREATE|O_RDWR); -  if(fd < 0){ -    printf(1, "fstests: cannot open sharedfd for writing"); -    return; -  } -  pid = fork(); -  memset(buf, pid==0?'c':'p', sizeof(buf)); -  for(i = 0; i < 100; i++){ -    if(write(fd, buf, sizeof(buf)) != sizeof(buf)){ -      printf(1, "fstests: write sharedfd failed\n"); -      break; -    } -  } -  if(pid == 0) -    exit(); -  else -    wait(); -  close(fd); -  fd = open("sharedfd", 0); -  if(fd < 0){ -    printf(1, "fstests: cannot open sharedfd for reading\n"); -    return; -  } -  nc = np = 0; -  while((n = read(fd, buf, sizeof(buf))) > 0){ -    for(i = 0; i < sizeof(buf); i++){ -      if(buf[i] == 'c') -        nc++; -      if(buf[i] == 'p') -        np++; -    } -  } -  close(fd); -  unlink("sharedfd"); -  if(nc == 1000 && np == 1000) -    printf(1, "sharedfd ok\n"); -  else -    printf(1, "sharedfd oops %d %d\n", nc, np); -} - -// two processes write two different files at the same -// time, to test block allocation. -void -twofiles() -{ -  int fd, pid, i, j, n, total; -  char *fname; - -  unlink("f1"); -  unlink("f2"); - -  pid = fork(); -  if(pid < 0){ -    puts("fork failed\n"); -    return; -  } - -  fname = pid ? "f1" : "f2"; -  fd = open(fname, O_CREATE | O_RDWR); -  if(fd < 0){ -    puts("create failed\n"); -    exit(); -  } - -  memset(buf, pid?'p':'c', 512); -  for(i = 0; i < 12; i++){ -    if((n = write(fd, buf, 500)) != 500){ -      printf(1, "write failed %d\n", n); -      exit(); -    } -  } -  close(fd); -  if(pid) -    wait(); -  else -    exit(); - -  for(i = 0; i < 2; i++){ -    fd = open(i?"f1":"f2", 0); -    total = 0; -    while((n = read(fd, buf, sizeof(buf))) > 0){ -      for(j = 0; j < n; j++){ -        if(buf[j] != (i?'p':'c')){ -          puts("wrong char\n"); -          exit(); -        } -      } -      total += n; -    } -    close(fd); -    if(total != 12*500){ -      printf(1, "wrong length %d\n", total); -      exit(); -    } -  } - -  unlink("f1"); -  unlink("f2"); - -  puts("twofiles ok\n"); -} - -// two processes create and delete files in same directory -void -createdelete() -{ -  int pid, i, fd; -  int n = 20; -  char name[32]; - -  pid = fork(); -  if(pid < 0){ -    puts("fork failed\n"); -    exit(); -  } - -  name[0] = pid ? 'p' : 'c'; -  name[2] = '\0'; -  for(i = 0; i < n; i++){ -    name[1] = '0' + i; -    fd = open(name, O_CREATE | O_RDWR); -    if(fd < 0){ -      puts("create failed\n"); -      exit(); -    } -    close(fd); -    if(i > 0 && (i % 2 ) == 0){ -      name[1] = '0' + (i / 2); -      if(unlink(name) < 0){ -        puts("unlink failed\n"); -        exit(); -      } -    } -  } - -  if(pid) -    exit(); -  else -    exit(); - -  for(i = 0; i < n; i++){ -    name[0] = 'p'; -    name[1] = '0' + i; -    fd = open(name, 0); -    if((i == 0 || i >= n/2) && fd < 0){ -      printf(1, "oops createdelete %s didn't exist\n", name); -      exit(); -    } else if((i >= 1 && i < n/2) && fd >= 0){ -      printf(1, "oops createdelete %s did exist\n", name); -      exit(); -    } -    if(fd >= 0) -      close(fd); - -    name[0] = 'c'; -    name[1] = '0' + i; -    fd = open(name, 0); -    if((i == 0 || i >= n/2) && fd < 0){ -      printf(1, "oops createdelete %s didn't exist\n", name); -      exit(); -    } else if((i >= 1 && i < n/2) && fd >= 0){ -      printf(1, "oops createdelete %s did exist\n", name); -      exit(); -    } -    if(fd >= 0) -      close(fd); -  } - -  for(i = 0; i < n; i++){ -    name[0] = 'p'; -    name[1] = '0' + i; -    unlink(name); -    name[0] = 'c'; -    unlink(name); -  } - -  printf(1, "createdelete ok\n"); -} - -// can I unlink a file and still read it? -void -unlinkread() -{ -  int fd, fd1; - -  fd = open("unlinkread", O_CREATE | O_RDWR); -  if(fd < 0){ -    puts("create unlinkread failed\n"); -    exit(); -  } -  write(fd, "hello", 5); -  close(fd); - -  fd = open("unlinkread", O_RDWR); -  if(fd < 0){ -    puts("open unlinkread failed\n"); -    exit(); -  } -  if(unlink("unlinkread") != 0){ -    puts("unlink unlinkread failed\n"); -    exit(); -  } - -  fd1 = open("unlinkread", O_CREATE | O_RDWR); -  write(fd1, "yyy", 3); -  close(fd1); - -  if(read(fd, buf, sizeof(buf)) != 5){ -    puts("unlinkread read failed"); -    exit(); -  } -  if(buf[0] != 'h'){ -    puts("unlinkread wrong data\n"); -    exit(); -  } -  if(write(fd, buf, 10) != 10){ -    puts("unlinkread write failed\n"); -    exit(); -  } -  close(fd); -  unlink("unlinkread"); -  puts("unlinkread ok\n"); -} - -void -linktest() -{ -  int fd; - -  unlink("lf1"); -  unlink("lf2"); - -  fd = open("lf1", O_CREATE|O_RDWR); -  if(fd < 0){ -    puts("create lf1 failed\n"); -    exit(); -  } -  if(write(fd, "hello", 5) != 5){ -    puts("write lf1 failed\n"); -    exit(); -  } -  close(fd); - -  if(link("lf1", "lf2") < 0){ -    puts("link lf1 lf2 failed\n"); -    exit(); -  } -  unlink("lf1"); - -  if(open("lf1", 0) >= 0){ -    puts("unlinked lf1 but it is still there!\n"); -    exit(); -  } - -  fd = open("lf2", 0); -  if(fd < 0){ -    puts("open lf2 failed\n"); -    exit(); -  } -  if(read(fd, buf, sizeof(buf)) != 5){ -    puts("read lf2 failed\n"); -    exit(); -  } -  close(fd); - -  if(link("lf2", "lf2") >= 0){ -    puts("link lf2 lf2 succeeded! oops\n"); -    exit(); -  } - -  unlink("lf2"); -  if(link("lf2", "lf1") >= 0){ -    puts("link non-existant succeeded! oops\n"); -    exit(); -  } - -  if(link(".", "lf1") >= 0){ -    puts("link . lf1 succeeded! oops\n"); -    exit(); -  } - -  puts("linktest ok\n"); -} - -// test concurrent create of the same file -void -concreate() -{ -  char file[3]; -  int i, pid, n, fd; -  char fa[40]; -  struct { -    unsigned short inum; -    char name[14]; -  } de; - -  file[0] = 'C'; -  file[2] = '\0'; -  for(i = 0; i < 40; i++){ -    file[1] = '0' + i; -    unlink(file); -    pid = fork(); -    if(pid && (i % 3) == 1){ -      link("C0", file); -    } else if(pid == 0 && (i % 5) == 1){ -      link("C0", file); -    } else { -      fd = open(file, O_CREATE | O_RDWR); -      if(fd < 0){ -        printf(1, "concreate create %s failed\n", file); -        exit(); -      } -      close(fd); -    } -    if(pid == 0) -      exit(); -    else -      wait(); -  } - -  memset(fa, 0, sizeof(fa)); -  fd = open(".", 0); -  n = 0; -  while(read(fd, &de, sizeof(de)) > 0){ -    if(de.inum == 0) -      continue; -    if(de.name[0] == 'C' && de.name[2] == '\0'){ -      i = de.name[1] - '0'; -      if(i < 0 || i >= sizeof(fa)){ -        printf(1, "concreate weird file %s\n", de.name); -        exit(); -      } -      if(fa[i]){ -        printf(1, "concreate duplicate file %s\n", de.name); -        exit(); -      } -      fa[i] = 1; -      n++; -    } -  } -  close(fd); - -  if(n != 40){ -    puts("concreate not enough files in directory listing\n"); -    exit(); -  } - -  for(i = 0; i < 40; i++){ -    file[1] = '0' + i; -    unlink(file); -  } - -  puts("concreate ok\n"); -} - -// directory that uses indirect blocks -void -bigdir() -{ -  int i, fd; -  char name[10]; - -  unlink("bd"); - -  fd = open("bd", O_CREATE); -  if(fd < 0){ -    puts("bigdir create failed\n"); -    exit(); -  } -  close(fd); - -  for(i = 0; i < 500; i++){ -    name[0] = 'x'; -    name[1] = '0' + (i / 64); -    name[2] = '0' + (i % 64); -    name[3] = '\0'; -    if(link("bd", name) != 0){ -      puts("bigdir link failed\n"); -      exit(); -    } -    puts("c"); -  } - -  unlink("bd"); -  for(i = 0; i < 500; i++){ -    name[0] = 'x'; -    name[1] = '0' + (i / 64); -    name[2] = '0' + (i % 64); -    name[3] = '\0'; -    if(unlink(name) != 0){ -      puts("bigdir unlink failed"); -      exit(); -    } -    puts("d"); -  } - -  puts("bigdir ok\n"); -} - -void -subdir() -{ -  int fd, cc; - -  unlink("ff"); -  if(mkdir("dd") != 0){ -    puts("subdir mkdir dd failed\n"); -    exit(); -  } - -  fd = open("dd/ff", O_CREATE | O_RDWR); -  if(fd < 0){ -    puts("create dd/ff failed\n"); -    exit(); -  } -  write(fd, "ff", 2); -  close(fd); - -  if(mkdir("/dd/dd") != 0){ -    puts("subdir mkdir dd/dd failed\n"); -    exit(); -  } - -  fd = open("dd/dd/ff", O_CREATE | O_RDWR); -  if(fd < 0){ -    puts("create dd/dd/ff failed\n"); -    exit(); -  } -  write(fd, "FF", 2); -  close(fd); - -  fd = open("dd/dd/../ff", 0); -  if(fd < 0){ -    puts("open dd/dd/../ff failed\n"); -    exit(); -  } -  cc = read(fd, buf, sizeof(buf)); -  if(cc != 2 || buf[0] != 'f'){ -    puts("dd/dd/../ff wrong content\n"); -    exit(); -  } -  close(fd); - -  if(link("dd/dd/ff", "dd/dd/ffff") != 0){ -    puts("link dd/dd/ff dd/dd/ffff failed\n"); -    exit(); -  } - -  if(unlink("dd/dd/ff") != 0){ -    puts("unlink dd/dd/ff failed\n"); -    exit(); -  } - -  if(chdir("dd") != 0){ -    puts("chdir dd failed\n"); -    exit(); -  } -  if(chdir("dd/../../dd") != 0){ -    puts("chdir dd/../../dd failed\n"); -    exit(); -  } -  if(chdir("./..") != 0){ -    puts("chdir ./.. failed\n"); -    exit(); -  } - -  fd = open("dd/dd/ffff", 0); -  if(fd < 0){ -    puts("open dd/dd/ffff failed\n"); -    exit(); -  } -  if(read(fd, buf, sizeof(buf)) != 2){ -    puts("read dd/dd/ffff wrong len\n"); -    exit(); -  } -  close(fd); - -  if(open("dd/dd/ff", 0) >= 0){ -    puts("open dd/dd/ff succeeded!\n"); -    exit(); -  } - -  if(open("dd/ff/ff", O_CREATE|O_RDWR) >= 0){ -    puts("create dd/ff/ff succeeded!\n"); -    exit(); -  } -  if(open("dd/xx/ff", O_CREATE|O_RDWR) >= 0){ -    puts("create dd/xx/ff succeeded!\n"); -    exit(); -  } -  if(open("dd", O_CREATE) >= 0){ -    puts("create dd succeeded!\n"); -    exit(); -  } -  if(open("dd", O_RDWR) >= 0){ -    puts("open dd rdwr succeeded!\n"); -    exit(); -  } -  if(open("dd", O_WRONLY) >= 0){ -    puts("open dd wronly succeeded!\n"); -    exit(); -  } -  if(link("dd/ff/ff", "dd/dd/xx") == 0){ -    puts("link dd/ff/ff dd/dd/xx succeeded!\n"); -    exit(); -  } -  if(link("dd/xx/ff", "dd/dd/xx") == 0){ -    puts("link dd/xx/ff dd/dd/xx succeeded!\n"); -    exit(); -  } -  if(link("dd/ff", "dd/dd/ffff") == 0){ -    puts("link dd/ff dd/dd/ffff succeeded!\n"); -    exit(); -  } -  if(mkdir("dd/ff/ff") == 0){ -    puts("mkdir dd/ff/ff succeeded!\n"); -    exit(); -  } -  if(mkdir("dd/xx/ff") == 0){ -    puts("mkdir dd/xx/ff succeeded!\n"); -    exit(); -  } -  if(mkdir("dd/dd/ffff") == 0){ -    puts("mkdir dd/dd/ffff succeeded!\n"); -    exit(); -  } -  if(unlink("dd/xx/ff") == 0){ -    puts("unlink dd/xx/ff succeeded!\n"); -    exit(); -  } -  if(unlink("dd/ff/ff") == 0){ -    puts("unlink dd/ff/ff succeeded!\n"); -    exit(); -  } -  if(chdir("dd/ff") == 0){ -    puts("chdir dd/ff succeeded!\n"); -    exit(); -  } -  if(chdir("dd/xx") == 0){ -    puts("chdir dd/xx succeeded!\n"); -    exit(); -  } - -  if(unlink("dd/dd/ffff") != 0){ -    puts("unlink dd/dd/ff failed\n"); -    exit(); -  } -  if(unlink("dd/ff") != 0){ -    puts("unlink dd/ff failed\n"); -    exit(); -  } - -  // unlink dd/dd -  // unlink dd - -  puts("subdir ok\n"); -} - -void -bigfile() -{ -  int fd, i, total, cc; - -  unlink("bigfile"); -  fd = open("bigfile", O_CREATE | O_RDWR); -  if(fd < 0){ -    puts("cannot create bigfile"); -    exit(); -  } -  for(i = 0; i < 20; i++){ -    memset(buf, i, 600); -    if(write(fd, buf, 600) != 600){ -      puts("write bigfile failed\n"); -      exit(); -    } -  } -  close(fd); - -  fd = open("bigfile", 0); -  if(fd < 0){ -    puts("cannot open bigfile\n"); -    exit(); -  } -  total = 0; -  for(i = 0; ; i++){ -    cc = read(fd, buf, 300); -    if(cc < 0){ -      puts("read bigfile failed\n"); -      exit(); -    } -    if(cc == 0) -      break; -    if(cc != 300){ -      puts("short read bigfile\n"); -      exit(); -    } -    if(buf[0] != i/2 || buf[299] != i/2){ -      puts("read bigfile wrong data\n"); -      exit(); -    } -    total += cc; -  } -  close(fd); -  if(total != 20*600){ -    puts("read bigfile wrong total\n"); -    exit(); -  } -  unlink("bigfile"); - -  puts("bigfile ok\n"); -} - -void -fourteen() -{ -  int fd; - -  if(mkdir("12345678901234") != 0){ -    puts("mkdir 12345678901234 failed\n"); -    exit(); -  } -  if(mkdir("12345678901234/123456789012345") != 0){ -    puts("mkdir 12345678901234/123456789012345 failed\n"); -    exit(); -  } -  fd = open("123456789012345/123456789012345/123456789012345", O_CREATE); -  if(fd < 0){ -    puts("create 123456789012345/123456789012345/123456789012345 failed\n"); -    exit(); -  } -  close(fd); -  fd = open("12345678901234/12345678901234/12345678901234", 0); -  if(fd < 0){ -    puts("open 12345678901234/12345678901234/12345678901234 failed\n"); -    exit(); -  } -  close(fd); - -  if(mkdir("12345678901234/12345678901234") == 0){ -    puts("mkdir 12345678901234/12345678901234 succeeded!\n"); -    exit(); -  } -  if(mkdir("123456789012345/12345678901234") == 0){ -    puts("mkdir 12345678901234/123456789012345 succeeded!\n"); -    exit(); -  } - -  puts("fourteen ok\n"); -} - -int -main(int argc, char *argv[]) -{ -  puts("fstests starting\n"); - -  fourteen(); -  bigfile(); -  subdir(); -  // bigdir(); // slow -  concreate(); -  linktest(); -  unlinkread(); -  createdelete(); -  twofiles(); -  sharedfd(); - -  puts("fstests finished\n"); -  exit(); -} diff --git a/user1.c b/user1.c deleted file mode 100644 index 267320e..0000000 --- a/user1.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "user.h" - -char buf[32]; - -int -main(void) -{ -  int pid, fds[2], n; - -  pipe(fds); -  pid = fork(); -  if(pid > 0){ -    write(fds[1], "xyz", 4); -    puts("w"); -  } else { -    n = read(fds[0], buf, sizeof(buf)); -    puts("r: "); -    puts(buf); -    puts("\n"); -  } -  for(;;); -} diff --git a/userfs.c b/userfs.c deleted file mode 100644 index b409f1e..0000000 --- a/userfs.c +++ /dev/null @@ -1,210 +0,0 @@ -#include "types.h" -#include "stat.h" -#include "user.h" -#include "fs.h" -#include "fcntl.h" - -// simple file system tests - -char buf[2000]; -char name[3]; -char *echo_args[] = { "echo", "hello", "goodbye", 0 }; -char *cat_args[] = { "cat", "readme", 0 }; -int stdout = 1; - -void -opentest(void) -{ -  int fd; - -  fd = open("echo", 0); -  if(fd >= 0){ -    printf(stdout, "open echo ok\n"); -    close(fd); -  } else { -    printf(stdout, "open echo failed!\n"); -    exit(); -  } -  fd = open("doesnotexist", 0); -  if(fd >= 0){ -    printf(stdout, "open doesnotexist succeeded!\n"); -    exit(); -  } else { -    printf(stdout, "open doesnotexist failed\n"); -  } -} - -void -writetest(void) -{ -  int fd; -  int i; - -  fd = open("small", O_CREATE|O_RDWR); -  if(fd >= 0){ -    printf(stdout, "creat small succeeded\n"); -  } else { -    printf(stdout, "error: creat small failed!\n"); -    exit(); -  } -  for(i = 0; i < 100; i++) { -    if(write(fd, "aaaaaaaaaa", 10) != 10) { -      printf(stdout, "error: write aa %d new file failed\n", i); -      exit(); -    } -    if(write(fd, "bbbbbbbbbb", 10) != 10) { -      printf(stdout, "error: write bb %d new file failed\n", i); -      exit(); -    } -  } -  printf(stdout, "writes done\n"); -  close(fd); -  fd = open("small", O_RDONLY); -  if(fd >= 0){ -    printf(stdout, "open small succeeded\n"); -  } else { -    printf(stdout, "error: open small failed!\n"); -    exit(); -  } -  i = read(fd, buf, 2000); -  if(i == 2000) { -    printf(stdout, "read succeeded\n"); -  } else { -    printf(stdout, "read failed\n"); -    exit(); -  } -  close(fd); - -  if(unlink("small") < 0) { -    printf(stdout, "unlink small failed\n"); -    exit(); -  } -} - -void -writetest1(void) -{ -  int i, fd, n; - -  printf(stdout, "big files\n"); - -  fd = open("big", O_CREATE|O_RDWR); -  if(fd < 0){ -    printf(stdout, "error: creat big failed!\n"); -    exit(); -  } - -  for(i = 0; i < MAXFILE; i++) { -    ((int*) buf)[0] = i; -    if(write(fd, buf, 512) != 512) { -      printf(stdout, "error: write big file failed\n", i); -      exit(); -    } -  } - -  close(fd); - -  fd = open("big", O_RDONLY); -  if(fd < 0){ -    printf(stdout, "error: open big failed!\n"); -    exit(); -  } - -  n = 0; -  for(;;) { -    i = read(fd, buf, 512); -    if(i == 0) { -      if(n == MAXFILE - 1) { -        printf(stdout, "read only %d blocks from big", n); -        exit(); -      } -      break; -    } else if(i != 512) { -      printf(stdout, "read failed %d\n", i); -      exit(); -    } -    if(((int*)buf)[0] != n) { -      printf(stdout, "read content of block %d is %d\n", -             n, ((int*)buf)[0]); -      exit(); -    } -    n++; -  } -  close(fd); -  if(unlink("big") < 0) { -    printf(stdout, "unlink big failed\n"); -    exit(); -  } -} - -void -createtest(void) -{ -  int i, fd; - -  printf(stdout, "many creates, followed by unlink\n"); - -  name[0] = 'a'; -  name[2] = '\0'; -  for(i = 0; i < 52; i++) { -    name[1] = '0' + i; -    fd = open(name, O_CREATE|O_RDWR); -    close(fd); -  } -  name[0] = 'a'; -  name[2] = '\0'; -  for(i = 0; i < 52; i++) { -    name[1] = '0' + i; -    unlink(name); -  } -} - -void dirtest(void) -{ -  printf(stdout, "mkdir\n"); - -  if(mkdir("dir0") < 0) { -    printf(stdout, "mkdir failed\n"); -    exit(); -  } - -  if(chdir("dir0") < 0) { -    printf(stdout, "chdir dir0 failed\n"); -    exit(); -  } - -  if(chdir("..") < 0) { -    printf(stdout, "chdir .. failed\n"); -    exit(); -  } - -  if(unlink("dir0") < 0) { -    printf(stdout, "unlink dir0 failed\n"); -    exit(); -  } -} - -void -exectest(void) -{ -  if(exec("echo", echo_args) < 0) { -    printf(stdout, "exec echo failed\n"); -    exit(); -  } -  if(exec("cat", cat_args) < 0) { -    printf(stdout, "exec cat failed\n"); -    exit(); -  } -} - -int -main(void) -{ -  printf(stdout, "userfs is running\n"); -  opentest(); -  writetest(); -  writetest1(); -  createtest(); -  exectest(); -  return 0; -} diff --git a/usertests.c b/usertests.c index 0b003bd..f8a3efe 100644 --- a/usertests.c +++ b/usertests.c @@ -1,9 +1,201 @@  #include "types.h"  #include "stat.h"  #include "user.h" +#include "fs.h"  #include "fcntl.h"  char buf[2048]; +char name[3]; +char *echo_args[] = { "echo", "hello", "goodbye", 0 }; +char *cat_args[] = { "cat", "README", 0 }; +int stdout = 1; + +// simple file system tests + +void +opentest(void) +{ +  int fd; + +  printf(stdout, "open test\n"); +  fd = open("echo", 0); +  if(fd < 0){ +    printf(stdout, "open echo failed!\n"); +    exit(); +  } +  close(fd); +  fd = open("doesnotexist", 0); +  if(fd >= 0){ +    printf(stdout, "open doesnotexist succeeded!\n"); +    exit(); +  } +  printf(stdout, "open test ok\n"); +} + +void +writetest(void) +{ +  int fd; +  int i; + +  printf(stdout, "small file test\n"); +  fd = open("small", O_CREATE|O_RDWR); +  if(fd >= 0){ +    printf(stdout, "creat small succeeded; ok\n"); +  } else { +    printf(stdout, "error: creat small failed!\n"); +    exit(); +  } +  for(i = 0; i < 100; i++) { +    if(write(fd, "aaaaaaaaaa", 10) != 10) { +      printf(stdout, "error: write aa %d new file failed\n", i); +      exit(); +    } +    if(write(fd, "bbbbbbbbbb", 10) != 10) { +      printf(stdout, "error: write bb %d new file failed\n", i); +      exit(); +    } +  } +  printf(stdout, "writes ok\n"); +  close(fd); +  fd = open("small", O_RDONLY); +  if(fd >= 0){ +    printf(stdout, "open small succeeded ok\n"); +  } else { +    printf(stdout, "error: open small failed!\n"); +    exit(); +  } +  i = read(fd, buf, 2000); +  if(i == 2000) { +    printf(stdout, "read succeeded ok\n"); +  } else { +    printf(stdout, "read failed\n"); +    exit(); +  } +  close(fd); + +  if(unlink("small") < 0) { +    printf(stdout, "unlink small failed\n"); +    exit(); +  } +  printf(stdout, "small file test ok\n"); +} + +void +writetest1(void) +{ +  int i, fd, n; + +  printf(stdout, "big files test\n"); + +  fd = open("big", O_CREATE|O_RDWR); +  if(fd < 0){ +    printf(stdout, "error: creat big failed!\n"); +    exit(); +  } + +  for(i = 0; i < MAXFILE; i++) { +    ((int*) buf)[0] = i; +    if(write(fd, buf, 512) != 512) { +      printf(stdout, "error: write big file failed\n", i); +      exit(); +    } +  } + +  close(fd); + +  fd = open("big", O_RDONLY); +  if(fd < 0){ +    printf(stdout, "error: open big failed!\n"); +    exit(); +  } + +  n = 0; +  for(;;) { +    i = read(fd, buf, 512); +    if(i == 0) { +      if(n == MAXFILE - 1) { +        printf(stdout, "read only %d blocks from big", n); +        exit(); +      } +      break; +    } else if(i != 512) { +      printf(stdout, "read failed %d\n", i); +      exit(); +    } +    if(((int*)buf)[0] != n) { +      printf(stdout, "read content of block %d is %d\n", +             n, ((int*)buf)[0]); +      exit(); +    } +    n++; +  } +  close(fd); +  if(unlink("big") < 0) { +    printf(stdout, "unlink big failed\n"); +    exit(); +  } +  printf(stdout, "big files ok\n"); +} + +void +createtest(void) +{ +  int i, fd; + +  printf(stdout, "many creates, followed by unlink test\n"); + +  name[0] = 'a'; +  name[2] = '\0'; +  for(i = 0; i < 52; i++) { +    name[1] = '0' + i; +    fd = open(name, O_CREATE|O_RDWR); +    close(fd); +  } +  name[0] = 'a'; +  name[2] = '\0'; +  for(i = 0; i < 52; i++) { +    name[1] = '0' + i; +    unlink(name); +  } +  printf(stdout, "many creates, followed by unlink; ok\n"); +} + +void dirtest(void) +{ +  printf(stdout, "mkdir test\n"); + +  if(mkdir("dir0") < 0) { +    printf(stdout, "mkdir failed\n"); +    exit(); +  } + +  if(chdir("dir0") < 0) { +    printf(stdout, "chdir dir0 failed\n"); +    exit(); +  } + +  if(chdir("..") < 0) { +    printf(stdout, "chdir .. failed\n"); +    exit(); +  } + +  if(unlink("dir0") < 0) { +    printf(stdout, "unlink dir0 failed\n"); +    exit(); +  } +  printf(stdout, "mkdir test\n"); +} + +void +exectest(void) +{ +  printf(stdout, "exec test\n"); +  if(exec("echo", echo_args) < 0) { +    printf(stdout, "exec echo failed\n"); +    exit(); +  } +}  // simple fork and pipe read/write @@ -14,7 +206,7 @@ pipe1(void)    int seq = 0, i, n, cc, total;    if(pipe(fds) != 0){ -    puts("pipe() failed\n"); +    printf(1, "pipe() failed\n");      exit();    }    pid = fork(); @@ -50,10 +242,10 @@ pipe1(void)      close(fds[0]);      wait();    } else { -    puts("fork() failed\n"); +    printf(1, "fork() failed\n");      exit();    } -  puts("pipe1 ok\n"); +  printf(1, "pipe1 ok\n");  }  // meant to be run w/ at most two CPUs @@ -96,7 +288,7 @@ preempt(void)    wait();    wait();    wait(); -  puts("preempt ok\n"); +  printf(1, "preempt ok\n");  }  // try to find any races between exit and wait @@ -120,7 +312,7 @@ exitwait(void)        exit();      }    } -  puts("exitwait ok\n"); +  printf(1, "exitwait ok\n");  }  void @@ -142,7 +334,7 @@ mem(void)      }      m1 = malloc(1024*20);      if(m1 == 0) { -      puts("couldn't allocate mem?!!\n"); +      printf(1, "couldn't allocate mem?!!\n");        exit();      }      free(m1); @@ -153,16 +345,706 @@ mem(void)    }  } +// More file system tests + +// two processes write to the same file descriptor +// is the offset shared? does inode locking work? +void +sharedfd() +{ +  int fd, pid, i, n, nc, np; +  char buf[10]; + +  unlink("sharedfd"); +  fd = open("sharedfd", O_CREATE|O_RDWR); +  if(fd < 0){ +    printf(1, "fstests: cannot open sharedfd for writing"); +    return; +  } +  pid = fork(); +  memset(buf, pid==0?'c':'p', sizeof(buf)); +  for(i = 0; i < 100; i++){ +    if(write(fd, buf, sizeof(buf)) != sizeof(buf)){ +      printf(1, "fstests: write sharedfd failed\n"); +      break; +    } +  } +  if(pid == 0) +    exit(); +  else +    wait(); +  close(fd); +  fd = open("sharedfd", 0); +  if(fd < 0){ +    printf(1, "fstests: cannot open sharedfd for reading\n"); +    return; +  } +  nc = np = 0; +  while((n = read(fd, buf, sizeof(buf))) > 0){ +    for(i = 0; i < sizeof(buf); i++){ +      if(buf[i] == 'c') +        nc++; +      if(buf[i] == 'p') +        np++; +    } +  } +  close(fd); +  unlink("sharedfd"); +  if(nc == 1000 && np == 1000) +    printf(1, "sharedfd ok\n"); +  else +    printf(1, "sharedfd oops %d %d\n", nc, np); +} + +// two processes write two different files at the same +// time, to test block allocation. +void +twofiles() +{ +  int fd, pid, i, j, n, total; +  char *fname; + +  printf(1, "twofiles test\n"); + +  unlink("f1"); +  unlink("f2"); + +  pid = fork(); +  if(pid < 0){ +    printf(1, "fork failed\n"); +    return; +  } + +  fname = pid ? "f1" : "f2"; +  fd = open(fname, O_CREATE | O_RDWR); +  if(fd < 0){ +    printf(1, "create failed\n"); +    exit(); +  } + +  memset(buf, pid?'p':'c', 512); +  for(i = 0; i < 12; i++){ +    if((n = write(fd, buf, 500)) != 500){ +      printf(1, "write failed %d\n", n); +      exit(); +    } +  } +  close(fd); +  if(pid) +    wait(); +  else +    exit(); + +  for(i = 0; i < 2; i++){ +    fd = open(i?"f1":"f2", 0); +    total = 0; +    while((n = read(fd, buf, sizeof(buf))) > 0){ +      for(j = 0; j < n; j++){ +        if(buf[j] != (i?'p':'c')){ +          printf(1, "wrong char\n"); +          exit(); +        } +      } +      total += n; +    } +    close(fd); +    if(total != 12*500){ +      printf(1, "wrong length %d\n", total); +      exit(); +    } +  } + +  unlink("f1"); +  unlink("f2"); + +  printf(1, "twofiles ok\n"); +} + +// two processes create and delete files in same directory +void +createdelete() +{ +  int pid, i, fd; +  int n = 20; +  char name[32]; + +  printf(1, "createdelete test\n"); +  pid = fork(); +  if(pid < 0){ +    printf(1, "fork failed\n"); +    exit(); +  } + +  name[0] = pid ? 'p' : 'c'; +  name[2] = '\0'; +  for(i = 0; i < n; i++){ +    name[1] = '0' + i; +    fd = open(name, O_CREATE | O_RDWR); +    if(fd < 0){ +      printf(1, "create failed\n"); +      exit(); +    } +    close(fd); +    if(i > 0 && (i % 2 ) == 0){ +      name[1] = '0' + (i / 2); +      if(unlink(name) < 0){ +        printf(1, "unlink failed\n"); +        exit(); +      } +    } +  } + +  if(pid==0) +    exit(); +  //  else +  //exit(); + +  for(i = 0; i < n; i++){ +    name[0] = 'p'; +    name[1] = '0' + i; +    fd = open(name, 0); +    if((i == 0 || i >= n/2) && fd < 0){ +      printf(1, "oops createdelete %s didn't exist\n", name); +      exit(); +    } else if((i >= 1 && i < n/2) && fd >= 0){ +      printf(1, "oops createdelete %s did exist\n", name); +      exit(); +    } +    if(fd >= 0) +      close(fd); + +    name[0] = 'c'; +    name[1] = '0' + i; +    fd = open(name, 0); +    if((i == 0 || i >= n/2) && fd < 0){ +      printf(1, "oops createdelete %s didn't exist\n", name); +      exit(); +    } else if((i >= 1 && i < n/2) && fd >= 0){ +      printf(1, "oops createdelete %s did exist\n", name); +      exit(); +    } +    if(fd >= 0) +      close(fd); +  } + +  for(i = 0; i < n; i++){ +    name[0] = 'p'; +    name[1] = '0' + i; +    unlink(name); +    name[0] = 'c'; +    unlink(name); +  } + +  printf(1, "createdelete ok\n"); +} + +// can I unlink a file and still read it? +void +unlinkread() +{ +  int fd, fd1; + +  printf(1, "unlinkread test\n"); +  fd = open("unlinkread", O_CREATE | O_RDWR); +  if(fd < 0){ +    printf(1, "create unlinkread failed\n"); +    exit(); +  } +  write(fd, "hello", 5); +  close(fd); + +  fd = open("unlinkread", O_RDWR); +  if(fd < 0){ +    printf(1, "open unlinkread failed\n"); +    exit(); +  } +  if(unlink("unlinkread") != 0){ +    printf(1, "unlink unlinkread failed\n"); +    exit(); +  } + +  fd1 = open("unlinkread", O_CREATE | O_RDWR); +  write(fd1, "yyy", 3); +  close(fd1); + +  if(read(fd, buf, sizeof(buf)) != 5){ +    printf(1, "unlinkread read failed"); +    exit(); +  } +  if(buf[0] != 'h'){ +    printf(1, "unlinkread wrong data\n"); +    exit(); +  } +  if(write(fd, buf, 10) != 10){ +    printf(1, "unlinkread write failed\n"); +    exit(); +  } +  close(fd); +  unlink("unlinkread"); +  printf(1, "unlinkread ok\n"); +} + +void +linktest() +{ +  int fd; + +  printf(1, "linktest\n"); + +  unlink("lf1"); +  unlink("lf2"); + +  fd = open("lf1", O_CREATE|O_RDWR); +  if(fd < 0){ +    printf(1, "create lf1 failed\n"); +    exit(); +  } +  if(write(fd, "hello", 5) != 5){ +    printf(1, "write lf1 failed\n"); +    exit(); +  } +  close(fd); + +  if(link("lf1", "lf2") < 0){ +    printf(1, "link lf1 lf2 failed\n"); +    exit(); +  } +  unlink("lf1"); + +  if(open("lf1", 0) >= 0){ +    printf(1, "unlinked lf1 but it is still there!\n"); +    exit(); +  } + +  fd = open("lf2", 0); +  if(fd < 0){ +    printf(1, "open lf2 failed\n"); +    exit(); +  } +  if(read(fd, buf, sizeof(buf)) != 5){ +    printf(1, "read lf2 failed\n"); +    exit(); +  } +  close(fd); + +  if(link("lf2", "lf2") >= 0){ +    printf(1, "link lf2 lf2 succeeded! oops\n"); +    exit(); +  } + +  unlink("lf2"); +  if(link("lf2", "lf1") >= 0){ +    printf(1, "link non-existant succeeded! oops\n"); +    exit(); +  } + +  if(link(".", "lf1") >= 0){ +    printf(1, "link . lf1 succeeded! oops\n"); +    exit(); +  } + +  printf(1, "linktest ok\n"); +} + +// test concurrent create of the same file +void +concreate() +{ +  char file[3]; +  int i, pid, n, fd; +  char fa[40]; +  struct { +    unsigned short inum; +    char name[14]; +  } de; + +  printf(1, "concreate test\n"); +  file[0] = 'C'; +  file[2] = '\0'; +  for(i = 0; i < 40; i++){ +    file[1] = '0' + i; +    unlink(file); +    pid = fork(); +    if(pid && (i % 3) == 1){ +      link("C0", file); +    } else if(pid == 0 && (i % 5) == 1){ +      link("C0", file); +    } else { +      fd = open(file, O_CREATE | O_RDWR); +      if(fd < 0){ +        printf(1, "concreate create %s failed\n", file); +        exit(); +      } +      close(fd); +    } +    if(pid == 0) +      exit(); +    else +      wait(); +  } + +  memset(fa, 0, sizeof(fa)); +  fd = open(".", 0); +  n = 0; +  while(read(fd, &de, sizeof(de)) > 0){ +    if(de.inum == 0) +      continue; +    if(de.name[0] == 'C' && de.name[2] == '\0'){ +      i = de.name[1] - '0'; +      if(i < 0 || i >= sizeof(fa)){ +        printf(1, "concreate weird file %s\n", de.name); +        exit(); +      } +      if(fa[i]){ +        printf(1, "concreate duplicate file %s\n", de.name); +        exit(); +      } +      fa[i] = 1; +      n++; +    } +  } +  close(fd); + +  if(n != 40){ +    printf(1, "concreate not enough files in directory listing\n"); +    exit(); +  } + +  for(i = 0; i < 40; i++){ +    file[1] = '0' + i; +    unlink(file); +  } + +  printf(1, "concreate ok\n"); +} + +// directory that uses indirect blocks +void +bigdir() +{ +  int i, fd; +  char name[10]; + +  printf(1, "bigdir test\n"); +  unlink("bd"); + +  fd = open("bd", O_CREATE); +  if(fd < 0){ +    printf(1, "bigdir create failed\n"); +    exit(); +  } +  close(fd); + +  for(i = 0; i < 500; i++){ +    name[0] = 'x'; +    name[1] = '0' + (i / 64); +    name[2] = '0' + (i % 64); +    name[3] = '\0'; +    if(link("bd", name) != 0){ +      printf(1, "bigdir link failed\n"); +      exit(); +    } +  } + +  unlink("bd"); +  for(i = 0; i < 500; i++){ +    name[0] = 'x'; +    name[1] = '0' + (i / 64); +    name[2] = '0' + (i % 64); +    name[3] = '\0'; +    if(unlink(name) != 0){ +      printf(1, "bigdir unlink failed"); +      exit(); +    } +  } + +  printf(1, "bigdir ok\n"); +} + +void +subdir() +{ +  int fd, cc; + +  printf(1, "subdir test\n"); + +  unlink("ff"); +  if(mkdir("dd") != 0){ +    printf(1, "subdir mkdir dd failed\n"); +    exit(); +  } + +  fd = open("dd/ff", O_CREATE | O_RDWR); +  if(fd < 0){ +    printf(1, "create dd/ff failed\n"); +    exit(); +  } +  write(fd, "ff", 2); +  close(fd); + +  if(mkdir("/dd/dd") != 0){ +    printf(1, "subdir mkdir dd/dd failed\n"); +    exit(); +  } + +  fd = open("dd/dd/ff", O_CREATE | O_RDWR); +  if(fd < 0){ +    printf(1, "create dd/dd/ff failed\n"); +    exit(); +  } +  write(fd, "FF", 2); +  close(fd); + +  fd = open("dd/dd/../ff", 0); +  if(fd < 0){ +    printf(1, "open dd/dd/../ff failed\n"); +    exit(); +  } +  cc = read(fd, buf, sizeof(buf)); +  if(cc != 2 || buf[0] != 'f'){ +    printf(1, "dd/dd/../ff wrong content\n"); +    exit(); +  } +  close(fd); + +  if(link("dd/dd/ff", "dd/dd/ffff") != 0){ +    printf(1, "link dd/dd/ff dd/dd/ffff failed\n"); +    exit(); +  } + +  if(unlink("dd/dd/ff") != 0){ +    printf(1, "unlink dd/dd/ff failed\n"); +    exit(); +  } + +  if(chdir("dd") != 0){ +    printf(1, "chdir dd failed\n"); +    exit(); +  } +  if(chdir("dd/../../dd") != 0){ +    printf(1, "chdir dd/../../dd failed\n"); +    exit(); +  } +  if(chdir("./..") != 0){ +    printf(1, "chdir ./.. failed\n"); +    exit(); +  } + +  fd = open("dd/dd/ffff", 0); +  if(fd < 0){ +    printf(1, "open dd/dd/ffff failed\n"); +    exit(); +  } +  if(read(fd, buf, sizeof(buf)) != 2){ +    printf(1, "read dd/dd/ffff wrong len\n"); +    exit(); +  } +  close(fd); + +  if(open("dd/dd/ff", 0) >= 0){ +    printf(1, "open dd/dd/ff succeeded!\n"); +    exit(); +  } + +  if(open("dd/ff/ff", O_CREATE|O_RDWR) >= 0){ +    printf(1, "create dd/ff/ff succeeded!\n"); +    exit(); +  } +  if(open("dd/xx/ff", O_CREATE|O_RDWR) >= 0){ +    printf(1, "create dd/xx/ff succeeded!\n"); +    exit(); +  } +  if(open("dd", O_CREATE) >= 0){ +    printf(1, "create dd succeeded!\n"); +    exit(); +  } +  if(open("dd", O_RDWR) >= 0){ +    printf(1, "open dd rdwr succeeded!\n"); +    exit(); +  } +  if(open("dd", O_WRONLY) >= 0){ +    printf(1, "open dd wronly succeeded!\n"); +    exit(); +  } +  if(link("dd/ff/ff", "dd/dd/xx") == 0){ +    printf(1, "link dd/ff/ff dd/dd/xx succeeded!\n"); +    exit(); +  } +  if(link("dd/xx/ff", "dd/dd/xx") == 0){ +    printf(1, "link dd/xx/ff dd/dd/xx succeeded!\n"); +    exit(); +  } +  if(link("dd/ff", "dd/dd/ffff") == 0){ +    printf(1, "link dd/ff dd/dd/ffff succeeded!\n"); +    exit(); +  } +  if(mkdir("dd/ff/ff") == 0){ +    printf(1, "mkdir dd/ff/ff succeeded!\n"); +    exit(); +  } +  if(mkdir("dd/xx/ff") == 0){ +    printf(1, "mkdir dd/xx/ff succeeded!\n"); +    exit(); +  } +  if(mkdir("dd/dd/ffff") == 0){ +    printf(1, "mkdir dd/dd/ffff succeeded!\n"); +    exit(); +  } +  if(unlink("dd/xx/ff") == 0){ +    printf(1, "unlink dd/xx/ff succeeded!\n"); +    exit(); +  } +  if(unlink("dd/ff/ff") == 0){ +    printf(1, "unlink dd/ff/ff succeeded!\n"); +    exit(); +  } +  if(chdir("dd/ff") == 0){ +    printf(1, "chdir dd/ff succeeded!\n"); +    exit(); +  } +  if(chdir("dd/xx") == 0){ +    printf(1, "chdir dd/xx succeeded!\n"); +    exit(); +  } + +  if(unlink("dd/dd/ffff") != 0){ +    printf(1, "unlink dd/dd/ff failed\n"); +    exit(); +  } +  if(unlink("dd/ff") != 0){ +    printf(1, "unlink dd/ff failed\n"); +    exit(); +  } + +  // unlink dd/dd +  // unlink dd + +  printf(1, "subdir ok\n"); +} + +void +bigfile() +{ +  int fd, i, total, cc; + +  printf(1, "bigfile test\n"); + +  unlink("bigfile"); +  fd = open("bigfile", O_CREATE | O_RDWR); +  if(fd < 0){ +    printf(1, "cannot create bigfile"); +    exit(); +  } +  for(i = 0; i < 20; i++){ +    memset(buf, i, 600); +    if(write(fd, buf, 600) != 600){ +      printf(1, "write bigfile failed\n"); +      exit(); +    } +  } +  close(fd); + +  fd = open("bigfile", 0); +  if(fd < 0){ +    printf(1, "cannot open bigfile\n"); +    exit(); +  } +  total = 0; +  for(i = 0; ; i++){ +    cc = read(fd, buf, 300); +    if(cc < 0){ +      printf(1, "read bigfile failed\n"); +      exit(); +    } +    if(cc == 0) +      break; +    if(cc != 300){ +      printf(1, "short read bigfile\n"); +      exit(); +    } +    if(buf[0] != i/2 || buf[299] != i/2){ +      printf(1, "read bigfile wrong data\n"); +      exit(); +    } +    total += cc; +  } +  close(fd); +  if(total != 20*600){ +    printf(1, "read bigfile wrong total\n"); +    exit(); +  } +  unlink("bigfile"); + +  printf(1, "bigfile test ok\n"); +} + +void +fourteen() +{ +  int fd; + +  printf(1, "fourteen test\n"); + +  if(mkdir("12345678901234") != 0){ +    printf(1, "mkdir 12345678901234 failed\n"); +    exit(); +  } +  if(mkdir("12345678901234/123456789012345") != 0){ +    printf(1, "mkdir 12345678901234/123456789012345 failed\n"); +    exit(); +  } +  fd = open("123456789012345/123456789012345/123456789012345", O_CREATE); +  if(fd < 0){ +    printf(1, "create 123456789012345/123456789012345/123456789012345 failed\n"); +    exit(); +  } +  close(fd); +  fd = open("12345678901234/12345678901234/12345678901234", 0); +  if(fd < 0){ +    printf(1, "open 12345678901234/12345678901234/12345678901234 failed\n"); +    exit(); +  } +  close(fd); + +  if(mkdir("12345678901234/12345678901234") == 0){ +    printf(1, "mkdir 12345678901234/12345678901234 succeeded!\n"); +    exit(); +  } +  if(mkdir("123456789012345/12345678901234") == 0){ +    printf(1, "mkdir 12345678901234/123456789012345 succeeded!\n"); +    exit(); +  } + +  printf(1, "fourteen ok\n"); +} +  int  main(int argc, char *argv[])  { -  puts("usertests starting\n"); +  printf(1, "usertests starting\n"); + +  opentest(); +  writetest(); +  writetest1(); +  createtest();    mem();    pipe1();    preempt();    exitwait(); -  puts("usertests finished\n"); +  fourteen(); +  bigfile(); +  subdir(); +  bigdir(); // slow +  concreate(); +  linktest(); +  unlinkread(); +  createdelete(); +  twofiles(); +  sharedfd(); + +  exectest(); +    exit();  } | 
