The purpose of this assignment is to become more familiar with the concepts of process control and signaling. You’ll do this by writing a simple Unix shell program.
Start by copying lab1a-handout.tar to your Linux Lab home directory.
tar xvf lab1a-handout.tar
to expand the tarfilemake
to compile and link some test routinesYou are tasked with implementing a unix shell! This sounds intimidating but it's really not so bad.
Your shell must be able to:
quit
and fg
quit
-- quits the shell programfg
-- brings a job that was started in the background (&
) to the foregroundCtrl-C
interrupt -- this should kill the foreground job (if running)Ctrl-Z
stop -- this should stop the foreground jobRemember, a shell is an interactive program that runs programs on behalf of the user. It follows a REPL interface: Read Evaluate Print Loop
The command line is a sequence of ASCII test words delimited by whitespace. The first word of this line will be either (1) the name of a built-in command or (2) an absolute pathname of an executable file. The remaining words on the line are command line arguments
&
, then the job runs in the background, which means the shell does not wait for the job to terminate before printing the prompt and awaiting the next command line. Otherwise, the job runs in the foreground, which means the shell waits for the job to terminate before awaiting the next command line.ONLY ONE JOB CAN RUN IN THE FOREGROUND AT A TIME
tsh> /bin/ls -l -d
Runs the ls command which will do a long listing on directory files
argc == 3
)argv[0] == "/bin/ls"
argv[1] == "-l"
argv[2] == "-d"
tsh> /bin/sleep 10 &
Runs the sleep command which will wait at least 10 seconds before ending
argc == 2
)argv[0] == "/bin/sleep"
argv[1] == "10"
You are only expected to be able to
&
)fg
)ctrl+c
ctrl+z
tsh>
ctrl-c
should cause a SIGINT
signal to be sent to the current foreground job as well as any descendents of the job. If there is no foreground job, then the signal should have no effectctrl-z
should cause a SIGTSTP
signal to be sent to the current foreground job as well as any descendents of the job. If there is no foreground job, then the signal should have no effect&
, then the new job should be run in the background. Otherwise, it should run the job in the foregroundquit
-- terminates the shellfg
-- restarts the stopped job by sending SIGCONT
and run it in the foregroundtsh
should recognize this event and print a message with the job's PID and a description of the offending signalYou are welcome to organize this in any way, but you may find it helpful to structure your code into the following methods:
eval
-- main routine that parses and interprets the command linebuiltin_cmd
-- recognize and interprets the built-in commandswaitfg
-- waits for a foreground job to completesigchld_handler
-- catches SIGCHILD signalssigint_handler
-- catches SIGINT (ctrl-c
) signalssigstp_handler
-- catches SIGTSTP (ctrl-z
) signalsUpload/submit tsh.c
to autolab.
This lab will be graded out of 100 points.
80pt
-- autograded20pt
-- discussion / comments of your implementation