user/usertests.c
void
concreate(void)
{
  enum { N = 40 };
  char file[3];
  int i, pid, n, fd;
  char fa[N];
  struct {
    ushort inum;
    char name[DIRSIZ];
  } de;

  printf("concreate test\n");
  file[0] = 'C';
  file[2] = '\0';
  for(i = 0; i < N; 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("concreate create %s failed\n", file);
        exit(1);
      }
      close(fd);
    }
    if(pid == 0)
      exit(0);
    else
      wait(0);
  }

  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("concreate weird file %s\n", de.name);
        exit(1);
      }
      if(fa[i]){
        printf("concreate duplicate file %s\n", de.name);
        exit(1);
      }
      fa[i] = 1;
      n++;
    }
  }
  close(fd);

  if(n != N){
    printf("concreate not enough files in directory listing\n");
    exit(1);
  }

  for(i = 0; i < N; i++){
    file[1] = '0' + i;
    pid = fork();
    if(pid < 0){
      printf("fork failed\n");
      exit(1);
    }
    if(((i % 3) == 0 && pid == 0) ||
       ((i % 3) == 1 && pid != 0)){
      close(open(file, 0));
      close(open(file, 0));
      close(open(file, 0));
      close(open(file, 0));
    } else {
      unlink(file);
      unlink(file);
      unlink(file);
      unlink(file);
    }
    if(pid == 0)
      exit(0);
    else
      wait(0);
  }

  printf("concreate ok\n");
}
// test concurrent create/link/unlink of the same file
test concurrent create/link/unlink of the same file
test concurrent create / link / unlink of the same file
void
concreate(void)
{
  enum { N = 40 };
  char file[3];
  int i, pid, n, fd;
  char fa[N];
  struct {
    ushort inum;
    char name[DIRSIZ];
  } de;
  printf("concreate test\n");
  file[0] = 'C';
  file[2] = '\0';
  for(i = 0; i < N; 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("concreate create %s failed\n", file);
        exit(1);
      }
      close(fd);
    }
    if(pid == 0)
      exit(0);
    else
      wait(0);
  }
  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("concreate weird file %s\n", de.name);
        exit(1);
      }
      if(fa[i]){
        printf("concreate duplicate file %s\n", de.name);
        exit(1);
      }
      fa[i] = 1;
      n++;
    }
  }
  close(fd);
  if(n != N){
    printf("concreate not enough files in directory listing\n");
    exit(1);
  }
  for(i = 0; i < N; i++){
    file[1] = '0' + i;
    pid = fork();
    if(pid < 0){
      printf("fork failed\n");
      exit(1);
    }
    if(((i % 3) == 0 && pid == 0) ||
       ((i % 3) == 1 && pid != 0)){
      close(open(file, 0));
      close(open(file, 0));
      close(open(file, 0));
      close(open(file, 0));
    } else {
      unlink(file);
      unlink(file);
      unlink(file);
      unlink(file);
    }
    if(pid == 0)
      exit(0);
    else
      wait(0);
  }
  printf("concreate ok\n");
}
void concreate ( void ) { enum { N = 40 } ; char file [ 3 ] ; int i , pid , n , fd ; char fa [ N ] ; struct { ushort inum ; char name [ DIRSIZ ] ; } de ; printf ( " \n " ) ; file [ 0 ] = ' ' ; file [ 2 ] = ' \0 ' ; for ( i = 0 ; i < N ; i ++ ) { file [ 1 ] = ' ' + i ; unlink ( file ) ; pid = fork ( ) ; if ( pid && ( i % 3 ) == 1 ) { link ( " " , file ) ; } else if ( pid == 0 && ( i % 5 ) == 1 ) { link ( " " , file ) ; } else { fd = open ( file , O_CREATE | O_RDWR ) ; if ( fd < 0 ) { printf ( " \n " , file ) ; exit ( 1 ) ; } close ( fd ) ; } if ( pid == 0 ) exit ( 0 ) ; else wait ( 0 ) ; } 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 ] == ' ' && de . name [ 2 ] == ' \0 ' ) { i = de . name [ 1 ] - ' ' ; if ( i < 0 || i >= sizeof ( fa ) ) { printf ( " \n " , de . name ) ; exit ( 1 ) ; } if ( fa [ i ] ) { printf ( " \n " , de . name ) ; exit ( 1 ) ; } fa [ i ] = 1 ; n ++ ; } } close ( fd ) ; if ( n != N ) { printf ( " \n " ) ; exit ( 1 ) ; } for ( i = 0 ; i < N ; i ++ ) { file [ 1 ] = ' ' + i ; pid = fork ( ) ; if ( pid < 0 ) { printf ( " \n " ) ; exit ( 1 ) ; } if ( ( ( i % 3 ) == 0 && pid == 0 ) || ( ( i % 3 ) == 1 && pid != 0 ) ) { close ( open ( file , 0 ) ) ; close ( open ( file , 0 ) ) ; close ( open ( file , 0 ) ) ; close ( open ( file , 0 ) ) ; } else { unlink ( file ) ; unlink ( file ) ; unlink ( file ) ; unlink ( file ) ; } if ( pid == 0 ) exit ( 0 ) ; else wait ( 0 ) ; } printf ( " \n " ) ; }
test concurrent create/link/unlink of the same file
test concurrent create / link / unlink of the same file