ast_comparator/test/student_data/handout/shlab-handout/cases/45_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)
{
    char *argv[MAXARGS];    
    int isBG;               
    pid_t pid;              
    sigset_t mask;          
    isBG = parseline(cmdline, argv);
    if (argv[0] == NULL)
        return;
    if (builtin_cmd(argv))
        return;
    if(sigemptyset(&mask) != 0){
        unix_error("sigemptyset error");
    }
    if(sigaddset(&mask, SIGCHLD) != 0){
        unix_error("sigaddset error");
    }
    if(sigprocmask(SIG_BLOCK, &mask, NULL) != 0){
        unix_error("sigprocmask error");
    }
    if((pid = fork()) < 0){
        unix_error("forking error");
        return;
    }
    if (pid) {
        addjob(jobs, pid, (isBG) ? BG : FG, cmdline);
        if (sigprocmask(SIG_UNBLOCK, &mask, NULL) != 0){
            unix_error("sigprocmask error");
        }
        if (isBG) {
            printf("[%d] (%d) %s", pid2jid(pid), pid, cmdline);
        } else {
            waitfg(pid);
        }
    }
    else {
        if(setpgid(0, 0) < 0) {
            unix_error("setpgid error");
        }
        if (sigprocmask(SIG_UNBLOCK, &mask, NULL) != 0){
            unix_error("sigprocmask error");
        }
        if (execvp(argv[0], argv) < 0) {
            printf("%s: Command not found\n", argv[0]);
            exit(0);
        }
    }
    return;
}
void eval ( char * cmdline ) { char * argv [ MAXARGS ] ; int isBG ; pid_t pid ; sigset_t mask ; isBG = parseline ( cmdline , argv ) ; if ( argv [ 0 ] == NULL ) return ; if ( builtin_cmd ( argv ) ) return ; if ( sigemptyset ( & mask ) != 0 ) { unix_error ( " " ) ; } if ( sigaddset ( & mask , SIGCHLD ) != 0 ) { unix_error ( " " ) ; } if ( sigprocmask ( SIG_BLOCK , & mask , NULL ) != 0 ) { unix_error ( " " ) ; } if ( ( pid = fork ( ) ) < 0 ) { unix_error ( " " ) ; return ; } if ( pid ) { addjob ( jobs , pid , ( isBG ) ? BG : FG , cmdline ) ; if ( sigprocmask ( SIG_UNBLOCK , & mask , NULL ) != 0 ) { unix_error ( " " ) ; } if ( isBG ) { printf ( " " , pid2jid ( pid ) , pid , cmdline ) ; } else { waitfg ( pid ) ; } } else { if ( setpgid ( 0 , 0 ) < 0 ) { unix_error ( " " ) ; } if ( sigprocmask ( SIG_UNBLOCK , & mask , NULL ) != 0 ) { unix_error ( " " ) ; } if ( execvp ( argv [ 0 ] , argv ) < 0 ) { printf ( " \n " , argv [ 0 ] ) ; exit ( 0 ) ; } } 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 .
/* stores the returned arguments of parseline */ /* if the job is background or not */ /* process id to identify the parent and child */ /* blocks signals */ // parse the input and execute immediately if possible // block sigchild //parent: register job to joblist, shell shoud get the signal so unblock them. //child: new process group(pgid), unblock mask, and then exec