## [CS:APP-ch8] Shell Lab

http://csapp.cs.cmu.edu/3e/labs.html

https://github.com/zhoudiqiu/Shell-lab/blob/master/lab5/tsh.c

### Target

implement

• eval, builtin_cmd, do_bgfg, waitfg
• sigchld_handler, sigint_handler, sigtstp_handler

### 0. Preparation

tshref: 正确的参考shell，要求自己实现后的shell和它的结果一样

make test01用trace01.txt来验证结果，可以参考make rtest01的结果

gdb makefile去掉参数O2,加上-g

### 1. void eval ( char*cmdline )

• If command is a built-in command, the shell program handles it immediately.
• Otherwise, the shell creates a child process to load and execute the program for command.

Hint

• In eval, the parent must use sigprocmaskto block SIGCHLD signals before it forks the child, then unblock these signals, again using sigprocmask after it adds the child to the job list by calling addjob.
• Since children inherit the blocked vectors of their parents, the child must be sure to then unblock SIGCHLD signals before it execs the new program.
• The parent needs to block the SIGCHLD signals in this way in order to avoid the race condition where the child is reaped by sigchld_handler (and thus removed from the job list) before the parent calls addjob.
• After the fork, but before the execve, the child process should call setpgid(0, 0), which puts the child in a new process group whose group ID is identical to the child’s PID. This ensures that there will be only one process, your shell, in the foreground process group. When you type ctrl-c, the shell should catch the resulting SIGINT and then forward it to the appropriate foreground job (or more precisely, the process group that contains the foreground job).

### 2.int builtin_cmd( char **argv)

• Four commands are to be built-in in the shell
• quit: exit the shell.
• jobs: List the running and stopped background jobs.

### 3. void waitfg( pid_t pid )

• shell should wait for foreground process
• This function should wait by sleeping for 1 second repeatedly until the specified process is no longer the foreground process (state = FG)

Hints

• In waitfg, use a busy loop around the sleep function.

### 4. void do_bgfg( char **argv )

• bg <job>: Change a stopped background job to a running background job.
• fg <job>: Change a stopped or running background job to a running in the foreground.
• The bg <job> command restarts \ by sending it a SIGCONTsignal, and then runs it in the background. The \ argument can be either a PID or a JID.
• The fg <job>command restarts \ by sending it a SIGCONTsignal, and then runs it in the foreground. The \ argument can be either a PID or a JID.

### 5.void sigchld_handler( int sig )

This is the shell’s handler for theSIGCHLD signal.

Hints

• In sigchld_handler, use exactly one call to waitpid

### 6. void sigint_handler ( int sig )

Hints

• When you implement your signal handlers, be sure to send SIGINT and SIGTSTP signals to the entire foreground process group, using -pid instead of pid in the argument to the kill function.
The sdriver.pl program tests for this error.