ast_comparator/test/student_data/handout/shlab-handout/cases/50_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 = (char**)(char*)malloc(MAXARGS * sizeof(char));
	int bg = parseline(cmdline, argv);
	if('b' <= argv[0][0] && argv[0][0] <= 'q')
	{
		if(builtin_cmd(argv) < 0)
			printf("%s: Command not found\n", argv[0]);
		return;
	}
	int argc = 0;
	char *ir_path = (char*)1, *or_path = (char*)1;
	int append = 0;
	while(argv[argc] != NULL)
	{
		if(ir_path == NULL)
			ir_path = argv[argc];
		else if(or_path == NULL)
			or_path = argv[argc];
		if(strcmp(argv[argc], "<") == 0)
			ir_path = NULL;
		else if(strcmp(argv[argc], ">") == 0)
		{
			or_path = argv[argc] = NULL;
			append = 0;
		}
		else if(strcmp(argv[argc], ">>") == 0)
		{
			or_path = argv[argc] = NULL;
			append = 1;
		}
		argc++;
	}
	int ir_fd = 0, or_fd = 0;
	if(ir_path != (char*)1)
	{
		if((ir_fd = open(ir_path, O_RDONLY)) < 0)
		{
  			printf("Input redirection error: %s\n", strerror(errno));
			return;
		}
	}
	if(or_path != (char*)1)
	{
		int flag = O_CREAT | O_WRONLY;
		if(append)
			flag |= O_APPEND;
		else
			flag |= O_TRUNC;
		if((or_fd = open(or_path, flag, S_IRUSR|S_IWUSR)) < 0)
		{
  			printf("Output redirection error: %s\n", strerror(errno));
			return;
		}
	}
	sigset_t sigset;
	sigemptyset(&sigset);
	sigaddset(&sigset, SIGCHLD);
	if(sigprocmask(SIG_BLOCK, &sigset, NULL) < 0)
		unix_error("sigprocmask error");
	pid_t pid;
	if((pid = fork()) == 0)	
	{
		if(setpgid(0, 0) < 0)
			unix_error("setpgid error");
		if(ir_fd > 0)
			if(dup2(ir_fd, 0) < 0)
				unix_error("dup2 error");
		if(or_fd > 0)
			if(dup2(or_fd, 1) < 0)
				unix_error("dup2 error");
		execve(argv[0], argv, environ);
		printf("%s: Command not found\n", argv[0]);
		exit(0);
	}
	else if(pid < 0)
		unix_error("fork error");
	else					
	{
		if(bg == 0)
		{
			addjob(jobs, pid, FG, cmdline, ir_fd, or_fd);
			if(sigprocmask(SIG_UNBLOCK, &sigset, NULL) < 0)
				unix_error("sigprocmask error");
			waitfg(pid);
		}
		else
		{
			addjob(jobs, pid, BG, cmdline, ir_fd, or_fd);
			if(sigprocmask(SIG_UNBLOCK, &sigset, NULL) < 0)
				unix_error("sigprocmask error");
			struct job_t* job = getjobpid(jobs, pid);
			printf("[%d] (%d) %s", job->jid, job->pid, job->cmdline);
		}
	}
}
void eval ( char * cmdline ) { char * * argv = ( char * * ) ( char * ) malloc ( MAXARGS * sizeof ( char ) ) ; int bg = parseline ( cmdline , argv ) ; if ( ' ' <= argv [ 0 ] [ 0 ] && argv [ 0 ] [ 0 ] <= ' ' ) { if ( builtin_cmd ( argv ) < 0 ) printf ( " \n " , argv [ 0 ] ) ; return ; } int argc = 0 ; char * ir_path = ( char * ) 1 , * or_path = ( char * ) 1 ; int append = 0 ; while ( argv [ argc ] != NULL ) { if ( ir_path == NULL ) ir_path = argv [ argc ] ; else if ( or_path == NULL ) or_path = argv [ argc ] ; if ( strcmp ( argv [ argc ] , " " ) == 0 ) ir_path = NULL ; else if ( strcmp ( argv [ argc ] , " " ) == 0 ) { or_path = argv [ argc ] = NULL ; append = 0 ; } else if ( strcmp ( argv [ argc ] , " " ) == 0 ) { or_path = argv [ argc ] = NULL ; append = 1 ; } argc ++ ; } int ir_fd = 0 , or_fd = 0 ; if ( ir_path != ( char * ) 1 ) { if ( ( ir_fd = open ( ir_path , O_RDONLY ) ) < 0 ) { printf ( " \n " , strerror ( errno ) ) ; return ; } } if ( or_path != ( char * ) 1 ) { int flag = O_CREAT | O_WRONLY ; if ( append ) flag |= O_APPEND ; else flag |= O_TRUNC ; if ( ( or_fd = open ( or_path , flag , S_IRUSR | S_IWUSR ) ) < 0 ) { printf ( " \n " , strerror ( errno ) ) ; return ; } } sigset_t sigset ; sigemptyset ( & sigset ) ; sigaddset ( & sigset , SIGCHLD ) ; if ( sigprocmask ( SIG_BLOCK , & sigset , NULL ) < 0 ) unix_error ( " " ) ; pid_t pid ; if ( ( pid = fork ( ) ) == 0 ) { if ( setpgid ( 0 , 0 ) < 0 ) unix_error ( " " ) ; if ( ir_fd > 0 ) if ( dup2 ( ir_fd , 0 ) < 0 ) unix_error ( " " ) ; if ( or_fd > 0 ) if ( dup2 ( or_fd , 1 ) < 0 ) unix_error ( " " ) ; execve ( argv [ 0 ] , argv , environ ) ; printf ( " \n " , argv [ 0 ] ) ; exit ( 0 ) ; } else if ( pid < 0 ) unix_error ( " " ) ; else { if ( bg == 0 ) { addjob ( jobs , pid , FG , cmdline , ir_fd , or_fd ) ; if ( sigprocmask ( SIG_UNBLOCK , & sigset , NULL ) < 0 ) unix_error ( " " ) ; waitfg ( pid ) ; } else { addjob ( jobs , pid , BG , cmdline , ir_fd , or_fd ) ; if ( sigprocmask ( SIG_UNBLOCK , & sigset , NULL ) < 0 ) unix_error ( " " ) ; struct job_t * job = getjobpid ( jobs , pid ) ; printf ( " " , job -> jid , job -> pid , job -> cmdline ) ; } } }
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 .
// Check built-in command // Count argc & find I/O redirection // Do I/O redirection // can do <. >, >> // redirection command should be the last of arguments. // Block SIGCHLD signal to prevent earlier sighandler // Child process // Separate group // I/O redirection // Goes to here when the path/file is invalid // Parent process