ast_comparator/test/student_data/handout/shlab-handout/cases/reference_5_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 bg;              
    struct cmdline_tokens tok;
    pid_t pid;           
    sigset_t set;        
    sigset_t oldset;     
    bg = parseline(cmdline, &tok); 
    if (!builtin_cmd(&tok)) {       
        if (sigemptyset(&set) != 0) {
            unix_error("Error in sigemptyset");
        }
        if (   sigaddset(&set, SIGCHLD)    != 0 
            || sigaddset(&set, SIGINT)     != 0
            || sigaddset(&set, SIGTSTP)    != 0) {
            unix_error("Error in sigaddset");
        }
        if (sigprocmask(SIG_BLOCK, &set, &oldset) != 0) {
            unix_error("Error in sigprocmask");
        }
        if ((pid = fork()) < 0) {       
            unix_error("Error in fork");
        }
        else if (pid == 0) {
            if (sigprocmask(SIG_SETMASK, &oldset, NULL) != 0) {
                unix_error("Error in sigprocmask");
            }
            if (setpgid(0, 0) != 0) {
                unix_error("Error in setgpid");
            }
            if (!bg) {
                tcsetpgrp(STDIN_FILENO, getpgrp());
            }
            redirect_IO(tok.infile, tok.outfile);
            if (execve(tok.argv[0], tok.argv, environ) < 0) {
                printf("%s: Command not found.\n", tok.argv[0]);
                exit(0);
            }
        }
        else {
            if (addjob(job_list, pid, bg?BG:FG, cmdline) == 0) {
                unix_error("Error in addjob");
            }
            struct job_t* job_ptr = getjobpid(job_list, pid);
            if (!bg) {  
                if (sigprocmask(SIG_SETMASK, &oldset, NULL) != 0) {
                    unix_error("Error in segprocmask");
                }
                wait_fgjob(job_ptr);
            }
            else {      
                printf("[%d] (%d) %s\n", job_ptr->jid, 
                        job_ptr->pid, job_ptr->cmdline);
                if (sigprocmask(SIG_SETMASK, &oldset, NULL) != 0) {
                    unix_error("Error in segprocmask");
                }
            }
        }
    }    
    if (bg == -1) return;               
    if (tok.argv[0] == NULL)  return;   
    return;
}
void eval ( char * cmdline ) { int bg ; struct cmdline_tokens tok ; pid_t pid ; sigset_t set ; sigset_t oldset ; bg = parseline ( cmdline , & tok ) ; if ( ! builtin_cmd ( & tok ) ) { if ( sigemptyset ( & set ) != 0 ) { unix_error ( " " ) ; } if ( sigaddset ( & set , SIGCHLD ) != 0 || sigaddset ( & set , SIGINT ) != 0 || sigaddset ( & set , SIGTSTP ) != 0 ) { unix_error ( " " ) ; } if ( sigprocmask ( SIG_BLOCK , & set , & oldset ) != 0 ) { unix_error ( " " ) ; } if ( ( pid = fork ( ) ) < 0 ) { unix_error ( " " ) ; } else if ( pid == 0 ) { if ( sigprocmask ( SIG_SETMASK , & oldset , NULL ) != 0 ) { unix_error ( " " ) ; } if ( setpgid ( 0 , 0 ) != 0 ) { unix_error ( " " ) ; } if ( ! bg ) { tcsetpgrp ( STDIN_FILENO , getpgrp ( ) ) ; } redirect_IO ( tok . infile , tok . outfile ) ; if ( execve ( tok . argv [ 0 ] , tok . argv , environ ) < 0 ) { printf ( " \n " , tok . argv [ 0 ] ) ; exit ( 0 ) ; } } else { if ( addjob ( job_list , pid , bg ? BG : FG , cmdline ) == 0 ) { unix_error ( " " ) ; } struct job_t * job_ptr = getjobpid ( job_list , pid ) ; if ( ! bg ) { if ( sigprocmask ( SIG_SETMASK , & oldset , NULL ) != 0 ) { unix_error ( " " ) ; } wait_fgjob ( job_ptr ) ; } else { printf ( " \n " , job_ptr -> jid , job_ptr -> pid , job_ptr -> cmdline ) ; if ( sigprocmask ( SIG_SETMASK , & oldset , NULL ) != 0 ) { unix_error ( " " ) ; } } } } if ( bg == -1 ) return ; if ( tok . argv [ 0 ] == NULL ) return ; return ; }
eval - Evaluate the command line that the user has just typed in
eval - Evaluate the command line that the user has just typed in
/* should the job run in bg or fg? */ /* store fork return value */ /* store blocked set value */ /* store unblocked set value */ /* Parse command line */ /* Not a builtin command */ /* Initialize set as empty set */ /* Add SIGCHLD, SIGINT, SIGTSTP signals to set */ /* 
         * Block SIGCHLD, SIGINT, SIGTSTP before fork child,
         * also store unblocked set value in oldset
         */ /* End of set manipulation */ /* Fork and Execute */ /////////////////////////////////////////////////////////////////// /* Child Process */ /* Use stored oldset as the unblocked set */ /* Make child process in a new process group different to tsh */ /* Set foreground process group ID to current 
                 * foreground process group ID associated with STDIN_FILENO
                 */ /* I/O redirection */ /* Execute the command */ ////////////////////////////////////////////////////////////////// /* Parent Process */ /* Add new job to job list based on the status of bg */ /* Get job pointer based on PID */ /* Foreground job */ /* Use stored oldset as unblocked set */ /* Wait foreground job to finish */ /* Background job */ /* Use stored oldset as unblocked set */ /* parsing error */ /* ignore empty lines */