ast_comparator/test/student_data/handout/shlab-handout/cases/reference_3_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];
    char buf[MAXLINE];
    int bg;
    sigset_t x;
    pid_t pid = 0;
    strcpy(buf,cmdline);
    bg = parseline(buf, argv);
    if (argv[0]==NULL)
        return; 
    if (!builtin_cmd(argv)) {
        if(sigemptyset(&x) == -1) {
            printf("Error in sigemptyset: returning to prompt\n"); 
            return;
        }
        if(sigaddset(&x, SIGCHLD) == -1) {
            printf("Error in sigaddset: returning to prompt\n");
            return;
        }
        if(sigprocmask(SIG_BLOCK, &x, NULL) == -1) {
            printf("Error in sigprocmask while blocking: returning to prompt\n");
            return;
        }
        if ((pid = Fork()) == 0) { 
            if(sigprocmask(SIG_UNBLOCK, &x, NULL) == -1) {
                printf("Error in sigprocmask while unblocking: returning to prompt\n");
                return;
            }
            if(setpgid(0,0) == -1) {
                printf("Error while putting child in a new process group: returning to prompt\n");
                return;
            }
            if (execve(argv[0], argv, environ) < 0) {
                printf("%s: Command not found.\n",argv[0]);
                exit(0);
            }
        }
        if (!addjob(jobs,pid,bg?BG:FG,cmdline))
            unix_error("Too many jobs.");
        if(sigprocmask(SIG_UNBLOCK, &x, NULL) == -1) {
            printf("Error in sigprocmask while unblocking: returning to prompt\n");
            return;
        }
        if (!bg) {
            waitfg(pid);
        } else {
            printf("[%d] (%d) %s",pid2jid(pid),pid,cmdline);
            fflush(stdout);
        }
    }
    return;
}
void eval ( char * cmdline ) { char * argv [ MAXARGS ] ; char buf [ MAXLINE ] ; int bg ; sigset_t x ; pid_t pid = 0 ; strcpy ( buf , cmdline ) ; bg = parseline ( buf , argv ) ; if ( argv [ 0 ] == NULL ) return ; if ( ! builtin_cmd ( argv ) ) { if ( sigemptyset ( & x ) == -1 ) { printf ( " \n " ) ; return ; } if ( sigaddset ( & x , SIGCHLD ) == -1 ) { printf ( " \n " ) ; return ; } if ( sigprocmask ( SIG_BLOCK , & x , NULL ) == -1 ) { printf ( " \n " ) ; return ; } if ( ( pid = Fork ( ) ) == 0 ) { if ( sigprocmask ( SIG_UNBLOCK , & x , NULL ) == -1 ) { printf ( " \n " ) ; return ; } if ( setpgid ( 0 , 0 ) == -1 ) { printf ( " \n " ) ; return ; } if ( execve ( argv [ 0 ] , argv , environ ) < 0 ) { printf ( " \n " , argv [ 0 ] ) ; exit ( 0 ) ; } } if ( ! addjob ( jobs , pid , bg ? BG : FG , cmdline ) ) unix_error ( " " ) ; if ( sigprocmask ( SIG_UNBLOCK , & x , NULL ) == -1 ) { printf ( " \n " ) ; return ; } if ( ! bg ) { waitfg ( pid ) ; } else { printf ( " " , pid2jid ( pid ) , pid , cmdline ) ; fflush ( stdout ) ; } } 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 .
// ignore empty lines  // Block SIGCHLD signals while creating child /* Child Process */ // Child must unblock SIGCHLD signals before execve // Ensure that only the shell is in the foreground process group // Execute Child process // Add child to the list // Parent must unblock SIGCHLD signals after adding child to jobs