ast_comparator/test/student_data/handout/shlab-handout/cases/reference_9_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) 
{
   The 'argv' vector is filled in by the parseline
   routine below. It provides the arguments needed
   for the execve() routine, which you'll need to
   use below to launch a process.
   The 'bg' variable is TRUE if the job should run
   in background mode or FALSE if it should run in FG
    char *argv[MAXARGS];
    int bg = parseline(cmdline, argv); returns true if bg job, false if foreground job
    pid_t pid;
    struct job_t *job;
    sigset_t masker;
    if (!builtin_cmd(argv)){if it is not a builtin_cmd, we need to fork and exec a child process, if it is a builtin_cmd we will process it with our builtin_cmd function 
        sigprocmask(SIG_BLOCK, &masker, NULL); blocks SIGCHLD singals before forking and will be unblocked after addjob is called.
        pid = fork();
        setpgid(0,0); set group id for all fg processes so bg processes do not associate with fg processes
        if(pid == 0){       if the return value of the fork is 0, it tells us that we are within the child process
            execv(argv[0], argv); this fork creates the child process, more specifically execv replaces currently executing program with newly loaded program image, PID unchanged
            printf("%s: Command not found\n", argv[0]);but if the command entered is not found, when we exec it, it will give us a negative value if the command is not found, if that is the case we need to exit so we don't end up running multiple instances of our shell.
            exit(0); this will never return unless the command is a bogus command, which is why I have cmdnotfound print       
        }       
        else{ if parent           
            if(!bg){ will execute if we are in the an FG process (bg is false)
                addjob(jobs, pid, FG, cmdline); add job to struct with fg state
                waitfg(pid); this makes the parent process wait for the child process and reap it, so we don't get zombies/defunct processes  
                    }
            else{
                addjob(jobs, pid, BG, cmdline); add job to struct with bg state               
                job = getjobpid(jobs, pid); get job id of recently added job
                printf("[%d] (%d) %s", job->jid, pid, cmdline);
            }
        }
        sigprocmask(SIG_UNBLOCK, &masker, NULL);unblocks the signals we blocked before add jobs 
    }   
    if (argv[0] == NULL){  
        return;   
        }
      return;
    }
void eval ( char * cmdline ) { char * argv [ MAXARGS ] ; int bg = parseline ( cmdline , argv ) ; pid_t pid ; struct job_t * job ; sigset_t masker ; if ( ! builtin_cmd ( argv ) ) { pid = fork ( ) ; setpgid ( 0 , 0 ) ; if ( pid == 0 ) { execv ( argv [ 0 ] , argv ) ; printf ( " \n " , argv [ 0 ] ) ; exit ( 0 ) ; } else { if ( ! bg ) { addjob ( jobs , pid , FG , cmdline ) ; waitfg ( pid ) ; } else { addjob ( jobs , pid , BG , cmdline ) ; job = getjobpid ( jobs , pid ) ; printf ( " " , job -> jid , pid , cmdline ) ; } } } if ( argv [ 0 ] == NULL ) { return ; } 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 .
/* Parse command line */ // // The 'argv' vector is filled in by the parseline // routine below. It provides the arguments needed // for the execve() routine, which you'll need to // use below to launch a process. // The 'bg' variable is TRUE if the job should run // in background mode or FALSE if it should run in FG //returns true if bg job, false if foreground job //if it is not a builtin_cmd, we need to fork and exec a child process, if it is a builtin_cmd we will process it with our builtin_cmd function  //sigprocmask(SIG_BLOCK, &masker, NULL); //blocks SIGCHLD singals before forking and will be unblocked after addjob is called. //set group id for all fg processes so bg processes do not associate with fg processes //if the return value of the fork is 0, it tells us that we are within the child process //this fork creates the child process, more specifically execv replaces currently executing program with newly loaded program image, PID unchanged //but if the command entered is not found, when we exec it, it will give us a negative value if the command is not found, if that is the case we need to exit so we don't end up running multiple instances of our shell. //this will never return unless the command is a bogus command, which is why I have cmdnotfound print        //if parent            //will execute if we are in the an FG process (bg is false) //add job to struct with fg state //this makes the parent process wait for the child process and reap it, so we don't get zombies/defunct processes   //add job to struct with bg state                //get job id of recently added job //sigprocmask(SIG_UNBLOCK, &masker, NULL);//unblocks the signals we blocked before add jobs  /* ignore empty lines */