ast_comparator/test/student_data/handout/shlab-handout/cases/51_tsh.c
/*
 * eval - Evaluate the command line that the user has just typed in
 *
 * If the user has requested a built-in command (quit, jobs, bg or fg)
 * then execute it immediately. Otherwise, fork a child process and
 * run the job in the context of the child. If the job is running in
 * the foreground, wait for it to terminate and then return.  Note:
 * each child process must have a unique process group ID so that our
 * background children don't receive SIGINT (SIGTSTP) from the kernel
 * when we type ctrl-c (ctrl-z) at the keyboard.
 */
Evaluate the command line that the user has just typed in
If the user has requested a built-in command (quit, jobs, bg or fg)
then execute it immediately. Otherwise, fork a child process and
run the job in the context of the child. If the job is running in
the foreground, wait for it to terminate and then return.  Note:
each child process must have a unique process group ID so that our
background children don't receive SIGINT (SIGTSTP) from the kernel
when we type ctrl-c (ctrl-z) at the keyboard.
Evaluate the command line that the user has just typed in If the user has requested a built - in command ( quit jobs bg or fg ) then execute it immediately . Otherwise fork a child process and run the job in the context of the child . If the job is running in the foreground wait for it to terminate and then return . Note : each child process must have a unique process group ID so that our background children don ' t receive SIGINT ( SIGTSTP ) from the kernel when we type ctrl - c ( ctrl - z ) at the keyboard .
void eval(char *cmdline)
{
  int i = 0;
  sigset_t mask;
  pid_t pid;
  char **argv = malloc(sizeof(char *)*MAXARGS);
  int flag = parseline(cmdline, argv);
  if(argv[0] == NULL)
    return;
  if(!builtin_cmd(argv)) { 
    sigemptyset(&mask); 
    sigaddset(&mask, SIGCHLD);
    sigprocmask(SIG_BLOCK, &mask, NULL);
    pid = fork(); 
    if(pid == 0) { 
      setpgid(0, 0);
      sigprocmask(SIG_UNBLOCK, &mask, NULL);
      if(execve(argv[0], argv, NULL) < 0) { 
        printf("%s: Command not found\n", argv[0]);
        exit(1);
      }
    }
    else if(pid > 0){ 
      if(flag == 0) {
        if(addjob(jobs, pid, FG, cmdline) == 0) { 
          return;
        }
        sigprocmask(SIG_UNBLOCK, &mask, NULL);
        waitfg(pid); 
      }
      else {
        if(addjob(jobs, pid, BG, cmdline) == 0) 
          return;
        sigprocmask(SIG_UNBLOCK, &mask, NULL);
        printf("[%d] (%d) ", pid2jid(pid), pid); 
        for(i=0; argv[i] != NULL; i++)
          printf("%s ", argv[i]);
        printf("&\n");
      }
    }
    else {  error: handle by printing error
      unix_error("Error in fork");
	}
  }	
  free(argv); 
  return;
}
void eval ( char * cmdline ) { int i = 0 ; sigset_t mask ; pid_t pid ; char * * argv = malloc ( sizeof ( char * ) * MAXARGS ) ; int flag = parseline ( cmdline , argv ) ; if ( argv [ 0 ] == NULL ) return ; if ( ! builtin_cmd ( argv ) ) { sigemptyset ( & mask ) ; sigaddset ( & mask , SIGCHLD ) ; sigprocmask ( SIG_BLOCK , & mask , NULL ) ; pid = fork ( ) ; if ( pid == 0 ) { setpgid ( 0 , 0 ) ; sigprocmask ( SIG_UNBLOCK , & mask , NULL ) ; if ( execve ( argv [ 0 ] , argv , NULL ) < 0 ) { printf ( " \n " , argv [ 0 ] ) ; exit ( 1 ) ; } } else if ( pid > 0 ) { if ( flag == 0 ) { if ( addjob ( jobs , pid , FG , cmdline ) == 0 ) { return ; } sigprocmask ( SIG_UNBLOCK , & mask , NULL ) ; waitfg ( pid ) ; } else { if ( addjob ( jobs , pid , BG , cmdline ) == 0 ) return ; sigprocmask ( SIG_UNBLOCK , & mask , NULL ) ; printf ( " " , pid2jid ( pid ) , pid ) ; for ( i = 0 ; argv [ i ] != NULL ; i ++ ) printf ( " " , argv [ i ] ) ; printf ( " \n " ) ; } } else { unix_error ( " " ) ; } } free ( argv ) ; return ; }
eval - Evaluate the command line that the user has just typed in
 If the user has requested a built-in command (quit, jobs, bg or fg)
 then execute it immediately.
eval - Evaluate the command line that the user has just typed in If the user has requested a built - in command ( quit jobs bg or fg ) then execute it immediately .
////////make argv//////////// ////////parse commend line//////// /////////execution//////////////// // when the cmdline is not a builtin command // make the sigchild mask set & block the signal // fork // child process: set pgid, unmask the signal and execute the command // if the command does not exist, print error & exit //parent process: add job to the joblist, unmask the signal, execute waitfg if it is foreground and else print the job information // check if the job list is full // wait until the process finishes // check if the job list is full // print the current job information // fork error: handle by printing error // free argv