ast_comparator/test/student_data/handout/shlab-handout/cases/42_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;				 
	pid_t lpid;			 
	sigset_t mask_all, mask_one, prev_one;
	Sigfillset(&mask_all);
	Sigemptyset(&mask_one);
	Sigaddset(&mask_one, SIGCHLD);
	strcpy(buf, cmdline);
	bg = parseline(buf, argv);
	if(argv[0] == NULL)
		return; 
	if(!builtin_cmd(argv)) {
		Sigprocmask(SIG_BLOCK, &mask_one, &prev_one); 
		if ((lpid = Fork()) == 0) { 
			if(setpgid(0, 0) != 0) {
				printf("setpgid error\n");
				exit(0);
			}
			Sigprocmask(SIG_SETMASK, &prev_one, NULL); 
			if(execve(argv[0], argv, environ) < 0) {
				printf("%s: Command not found.\n", argv[0]);
			}
		}
		if(!bg) {
			Addjob(jobs, lpid, FG, cmdline);
			Sigprocmask(SIG_SETMASK, &prev_one, NULL);
			waitfg(lpid);
		}
		else {
			int jobidx;
			Addjob(jobs, lpid, BG, cmdline);		
			if((jobidx = pid2jid(lpid)) == 0) {
				printf("no such job\n");
				exit(0);
			} 		
			Sigprocmask(SIG_SETMASK, &prev_one, NULL);
			printf("[%d] (%d) %s", jobidx, lpid, cmdline);
		}
	}
	return;
}
void eval ( char * cmdline ) { char * argv [ MAXARGS ] ; char buf [ MAXLINE ] ; int bg ; pid_t lpid ; sigset_t mask_all , mask_one , prev_one ; Sigfillset ( & mask_all ) ; Sigemptyset ( & mask_one ) ; Sigaddset ( & mask_one , SIGCHLD ) ; strcpy ( buf , cmdline ) ; bg = parseline ( buf , argv ) ; if ( argv [ 0 ] == NULL ) return ; if ( ! builtin_cmd ( argv ) ) { Sigprocmask ( SIG_BLOCK , & mask_one , & prev_one ) ; if ( ( lpid = Fork ( ) ) == 0 ) { if ( setpgid ( 0 , 0 ) != 0 ) { printf ( " \n " ) ; exit ( 0 ) ; } Sigprocmask ( SIG_SETMASK , & prev_one , NULL ) ; if ( execve ( argv [ 0 ] , argv , environ ) < 0 ) { printf ( " \n " , argv [ 0 ] ) ; } } if ( ! bg ) { Addjob ( jobs , lpid , FG , cmdline ) ; Sigprocmask ( SIG_SETMASK , & prev_one , NULL ) ; waitfg ( lpid ) ; } else { int jobidx ; Addjob ( jobs , lpid , BG , cmdline ) ; if ( ( jobidx = pid2jid ( lpid ) ) == 0 ) { printf ( " \n " ) ; exit ( 0 ) ; } Sigprocmask ( SIG_SETMASK , & prev_one , NULL ) ; printf ( " " , jobidx , lpid , cmdline ) ; } } 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 .
/* argument list */ /* holds modified command line */ /* whether do job in background */ /* process id  - local variable */ /* ignore empty lines */ /* block SIGCHLD */ /* child runs */ /* the child now run in group id with its own pid 
			 * There's only 1 process in this group
			 * */ /* unblock SIGCHLD */ /* Parents waits for foreground job to terminate */ /* before unblock the signal add jobs */ /* wait for child finishing */ /* In the case of background job, parents don't need to wait */