hw_sh.c
// Execute cmd.  Never returns.
Execute cmd.  Never returns.
Execute cmd . Never returns .
void
runcmd(struct cmd *cmd)
{
  int p[2], r;
  struct execcmd *ecmd;
  struct pipecmd *pcmd;
  struct redircmd *rcmd;
  char *root = "/bin/";
  char *usr_root = "/usr/bin/";
  char *path = (char *) malloc(100 * sizeof(char)); 
  if(cmd == 0)
    _exit(0);
  switch(cmd->type){
  default:
    fprintf(stderr, "unknown runcmd\n");
    _exit(-1);
  case ' ':
    ecmd = (struct execcmd*)cmd;
    if(ecmd->argv[0] == 0)
      _exit(0);
    if (execv(ecmd->argv[0], ecmd->argv) < 0) {
      strcpy(path, root);
      strcat(path, ecmd->argv[0]);
      if (execv(path, ecmd->argv) < 0) {
        strcpy(path, usr_root);
        strcat(path, ecmd->argv[0]);
        if (execv(path, ecmd->argv) < 0)
          /bin as well
          fprintf(stderr, "unknown command:%s\n", ecmd->argv[0]);
      }
    }
    break;
  case '>':
  case '<':
    rcmd = (struct redircmd*)cmd;
    close(rcmd->fd);           
    if ((r = open(rcmd->file, rcmd->flags, S_IWUSR | S_IRUSR)) < 0) {
      fprintf(stderr, "open failed.\n");
      exit(0);
    }
    runcmd(rcmd->cmd);
    break;
  case '|':
    pcmd = (struct pipecmd*)cmd;
    int p[2];
    if (pipe(p) < 0) {
      perror("pipe");
      exit(0);
    }
    if (fork1() == 0) {
      close(1);
      dup(p[1]); 
      runcmd(pcmd->left);
    }
    if (fork1() == 0) {
      close(0);
      dup(p[0]); 
      runcmd(pcmd->right);
    }
    wait(&r);
    wait(&r);
    break;
  }    
  _exit(0);
}
void runcmd ( struct cmd * cmd ) { int p [ 2 ] , r ; struct execcmd * ecmd ; struct pipecmd * pcmd ; struct redircmd * rcmd ; char * root = " " ; char * usr_root = " " ; char * path = ( char * ) malloc ( 100 * sizeof ( char ) ) ; if ( cmd == 0 ) _exit ( 0 ) ; switch ( cmd -> type ) { default : fprintf ( stderr , " \n " ) ; _exit ( -1 ) ; case ' ' : ecmd = ( struct execcmd * ) cmd ; if ( ecmd -> argv [ 0 ] == 0 ) _exit ( 0 ) ; if ( execv ( ecmd -> argv [ 0 ] , ecmd -> argv ) < 0 ) { strcpy ( path , root ) ; strcat ( path , ecmd -> argv [ 0 ] ) ; if ( execv ( path , ecmd -> argv ) < 0 ) { strcpy ( path , usr_root ) ; strcat ( path , ecmd -> argv [ 0 ] ) ; if ( execv ( path , ecmd -> argv ) < 0 ) fprintf ( stderr , " \n " , ecmd -> argv [ 0 ] ) ; } } break ; case ' ' : case ' ' : rcmd = ( struct redircmd * ) cmd ; close ( rcmd -> fd ) ; if ( ( r = open ( rcmd -> file , rcmd -> flags , S_IWUSR | S_IRUSR ) ) < 0 ) { fprintf ( stderr , " \n " ) ; exit ( 0 ) ; } runcmd ( rcmd -> cmd ) ; break ; case ' ' : pcmd = ( struct pipecmd * ) cmd ; int p [ 2 ] ; if ( pipe ( p ) < 0 ) { perror ( " " ) ; exit ( 0 ) ; } if ( fork1 ( ) == 0 ) { close ( 1 ) ; dup ( p [ 1 ] ) ; runcmd ( pcmd -> left ) ; } if ( fork1 ( ) == 0 ) { close ( 0 ) ; dup ( p [ 0 ] ) ; runcmd ( pcmd -> right ) ; } wait ( & r ) ; wait ( & r ) ; break ; } _exit ( 0 ) ; }
Execute cmd.
Execute cmd .
// 一定要有足够的空间。 // fprintf(stderr, "exec not implemented\n"); // Your code here ... //path doesn't in current dir. //path doesn't in /usr //path doesn't in /usr/bin as well // fprintf(stderr, "redir not implemented\n"); // Your code here ... //release the fd so that it can reuse // '>' : 1, '<' : 0 //now the fd is by the file. //when you print(), it should print the content to the file. // printf("fuck"); // fprintf(stderr, "pipe not implemented\n"); // Your code here ... // left process //release fd so that it can reuse later // ret is 1, and it refer to the p[1](write site of pipe) // close(p[0]); // close(p[1]); //right process // ret is 0, and it refer to the p[0](read site of pipe) // close(p[0]); // close(p[1]); // close(p[0]); // close(p[1]);