ast_comparator/test/student_data/handout/shlab-handout/cases/reference_26_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 cmd_tokens;    
    pid_t pid;                           
    int fd;                              
    int oldfd;                           
    struct job_t *pjob;                  
    sigset_t sigchld_mask;               
    sigset_t sigint_mask;                
    sigset_t sigtstp_mask;               
    if (sigemptyset(&sigchld_mask)) {
        unix_error("main: sigemptyset error");
        exit(1);
    }
    if (sigaddset(&sigchld_mask, SIGCHLD)) {
        unix_error("main: sigaddset error");
        exit(1);
    }
    if (sigemptyset(&sigint_mask)) {
        unix_error("main: sigemptyset error");
        exit(1);
    }
    if (sigaddset(&sigint_mask, SIGINT)) {
        unix_error("main: sigaddset error");
        exit(1);
    }
    if (sigemptyset(&sigtstp_mask)) {
        unix_error("main: sigemptyset error");
        exit(1);
    }
    if (sigaddset(&sigtstp_mask, SIGTSTP)) {
        unix_error("main: sigaddset error");
        exit(1);
    }
    bg = parseline(cmdline, &cmd_tokens) + 1;
    if (bg == 0 || cmd_tokens.argv[0] == NULL) {
        return;
    }
    if (!builtin_cmd(cmd_tokens)) {
        if (addjob(jobs, 1, bg, cmdline)) {
            if (sigprocmask(SIG_BLOCK, &sigchld_mask, NULL)) {
                unix_error("eval: sigprocmask error");
                exit(1);
            }
            if (sigprocmask(SIG_BLOCK, &sigint_mask, NULL)) {
                unix_error("eval: sigprocmask error");
                exit(1);
            }
            if (sigprocmask(SIG_BLOCK, &sigtstp_mask, NULL)) {
                unix_error("eval: sigprocmask error");
                exit(1);
            }
            if ((pid = fork()) == 0) {
                if (sigprocmask(SIG_UNBLOCK, &sigchld_mask, NULL)) {
                    unix_error("eval: sigprocmask error");
                    exit(1);
                }
                if (sigprocmask(SIG_UNBLOCK, &sigint_mask, NULL)) {
                    unix_error("eval: sigprocmask error");
                    exit(1);
                }
                if (sigprocmask(SIG_UNBLOCK, &sigtstp_mask, NULL)) {
                    unix_error("eval: sigprocmask error");
                    exit(1);
                }
                if (setpgid(0, 0)) { 
                    unix_error("eval: setpgid error");
                    exit(1);
                }
                oldfd = 0;
                if (cmd_tokens.infile) {
                    fd = open(cmd_tokens.infile, O_RDONLY, 0);
                    dup2(fd, STDIN_FILENO);
                }
                if (cmd_tokens.outfile) {
                    oldfd = open(cmd_tokens.outfile, O_RDONLY, 0);
                    dup2(STDOUT_FILENO, oldfd);
                    fd = open(cmd_tokens.outfile, O_WRONLY, 0);
                    dup2(fd, STDOUT_FILENO);
                }
                if (execve(cmd_tokens.argv[0], cmd_tokens.argv, environ) < 0) {
                    if (oldfd) {
                        dup2(oldfd, STDOUT_FILENO);
                    }
                    printf("%s: Command not found\n", cmd_tokens.argv[0]);
                    exit(0);
                }
            }
            if (nextjid == 1) {
                pjob = getjobjid(jobs, MAXJOBS);
            } else {
                pjob = getjobjid(jobs, nextjid - 1);
            }
            pjob->pid = pid;
            if (sigprocmask(SIG_UNBLOCK, &sigint_mask, NULL)) {
                unix_error("eval: sigprocmask error");
                exit(1);
            }
            if (sigprocmask(SIG_UNBLOCK, &sigtstp_mask, NULL)) {
                unix_error("eval: sigprocmask error");
                exit(1);
            }
            if (bg == FG) {     
                waitfg(pid);
            } else {            
                printf("[%d] (%d) %s\n", pjob->jid, pjob->pid, pjob->cmdline);
            }
            if (sigprocmask(SIG_UNBLOCK, &sigchld_mask, NULL)) {
                unix_error("eval: sigprocmask error");
                exit(1);
            }
        } else {
            printf("eval: addjob error\n");
        }
    }
    return;
}
void eval ( char * cmdline ) { int bg ; struct cmdline_tokens cmd_tokens ; pid_t pid ; int fd ; int oldfd ; struct job_t * pjob ; sigset_t sigchld_mask ; sigset_t sigint_mask ; sigset_t sigtstp_mask ; if ( sigemptyset ( & sigchld_mask ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( sigaddset ( & sigchld_mask , SIGCHLD ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( sigemptyset ( & sigint_mask ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( sigaddset ( & sigint_mask , SIGINT ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( sigemptyset ( & sigtstp_mask ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( sigaddset ( & sigtstp_mask , SIGTSTP ) ) { unix_error ( " " ) ; exit ( 1 ) ; } bg = parseline ( cmdline , & cmd_tokens ) + 1 ; if ( bg == 0 || cmd_tokens . argv [ 0 ] == NULL ) { return ; } if ( ! builtin_cmd ( cmd_tokens ) ) { if ( addjob ( jobs , 1 , bg , cmdline ) ) { if ( sigprocmask ( SIG_BLOCK , & sigchld_mask , NULL ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( sigprocmask ( SIG_BLOCK , & sigint_mask , NULL ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( sigprocmask ( SIG_BLOCK , & sigtstp_mask , NULL ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( ( pid = fork ( ) ) == 0 ) { if ( sigprocmask ( SIG_UNBLOCK , & sigchld_mask , NULL ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( sigprocmask ( SIG_UNBLOCK , & sigint_mask , NULL ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( sigprocmask ( SIG_UNBLOCK , & sigtstp_mask , NULL ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( setpgid ( 0 , 0 ) ) { unix_error ( " " ) ; exit ( 1 ) ; } oldfd = 0 ; if ( cmd_tokens . infile ) { fd = open ( cmd_tokens . infile , O_RDONLY , 0 ) ; dup2 ( fd , STDIN_FILENO ) ; } if ( cmd_tokens . outfile ) { oldfd = open ( cmd_tokens . outfile , O_RDONLY , 0 ) ; dup2 ( STDOUT_FILENO , oldfd ) ; fd = open ( cmd_tokens . outfile , O_WRONLY , 0 ) ; dup2 ( fd , STDOUT_FILENO ) ; } if ( execve ( cmd_tokens . argv [ 0 ] , cmd_tokens . argv , environ ) < 0 ) { if ( oldfd ) { dup2 ( oldfd , STDOUT_FILENO ) ; } printf ( " \n " , cmd_tokens . argv [ 0 ] ) ; exit ( 0 ) ; } } if ( nextjid == 1 ) { pjob = getjobjid ( jobs , MAXJOBS ) ; } else { pjob = getjobjid ( jobs , nextjid - 1 ) ; } pjob -> pid = pid ; if ( sigprocmask ( SIG_UNBLOCK , & sigint_mask , NULL ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( sigprocmask ( SIG_UNBLOCK , & sigtstp_mask , NULL ) ) { unix_error ( " " ) ; exit ( 1 ) ; } if ( bg == FG ) { waitfg ( pid ) ; } else { printf ( " \n " , pjob -> jid , pjob -> pid , pjob -> cmdline ) ; } if ( sigprocmask ( SIG_UNBLOCK , & sigchld_mask , NULL ) ) { unix_error ( " " ) ; exit ( 1 ) ; } } else { printf ( " \n " ) ; } } 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 .
// Background or foreground // Command line tokens // Processing ID // File discriptor // Temp file discriptor // Job pointer // SIGCHLD mask // SIGINT mask // SIGTSTP mask /* Initializing Masks */ // If line is empty, i.e., there are no arguments // If job list is not full // TODO: find tutorial link and add here // Set group ID // Foreground job // Background job