Team-FLY |
11.8 Job Control for ushThis section describes an implementation of job control for ush . Start by testing ush7 in the following cases to make sure that it correctly handles the SIGINT and SIGQUIT .
11.8.1 A job list objectTo do job control, ush must keep track of its children. Use a list object similar to the one used in Program 2.9 to keep a program history. The nodes in the list should have the following structure. typedef enum jstatus {FOREGROUND, BACKGROUND, STOPPED, DONE, TERMINATED} job_status_t; typedef struct job_struct { char *cmdstring; pid_t pgid; int job; job_status_t jobstat; struct job_struct *next; } joblist_t; static joblist_t *jobhead = NULL; static joblist_t *jobtail = NULL; Place the list structure in a separate file along with the following functions to manipulate the job list. int add(pid_t pgid, char *cmd, job_status_t status);
int delete(int job);
showjobs(void);
int setstatus(int job, job_status_t status);
int getstatus(int job, job_status_t *pstatus);
pid_t getprocess(int job);
int getlargest(void);
Write a driver program to thoroughly test the list functions independently of ush . 11.8.2 The job list in ushAfter the job list functions are working, add the job list object to ush as follows .
Test ush with the job list. Do not add job control in this step. Execute the jobs command frequently to see the status of the background processes. Carefully experiment with an existing shell that has job control. Make sure that ush handles background and foreground processes similarly. 11.8.3 Job control in ushIncorporate job control into ush by adding the following commands to ush in addition to the jobs command of the previous section.
Some of these commands refer to the current job. When there are several jobs, one is the current job . The current job starts out as the first background job to be started. A user can make another job the current job by bringing it to the foreground with fg . The ush shell now must handle SIGCONT , SIGTSTP , SIGTTIN and SIGTTOU in addition to SIGINT and SIGQUIT . When ush detects that a child has stopped because of a SIGTTIN or a SIGTTOU , it writes an informative message to standard error to notify the user that the child is waiting for input or output, respectively. The user can move that job to the foreground to read from or write to the controlling terminal. Test the program thoroughly. Pay particular attention to how your regular shell does job control and adjust ush to look as similar as possible. 11.8.4 Process behavior in waiting for a pipelineWhat happens when a shell starts a pipeline in the foreground and one of the processes in the pipeline terminates? The result depends on which process in the pipeline is the child of the shell. Exercise 11.36Make a new version of showid from Exercise 11.28 on page 395 that sleeps for one minute after displaying the IDs. Call the new program showidsleep . Run ush7 with each of the following command lines. What happens? showidsleep first showid second showid first showidsleep second Answer: For the first command line, the shell displays the prompt after one minute since the first command in the pipeline is the child of the shell. For the second command line, the shell displays the prompt immediately since it waits only for the first command in the pipeline. This is probably not the desired behavior. Typically, a pipeline consists of a sequence of filters, and the last one in the sequence is the last to finish. Exercise 11.37How would you solve the problem described in Exercise 11.36? Answer: One solution would be to rewrite executecmdpipe so that the last command of the pipeline was executed by the first process created. A better solution would be to have all of the processes in the pipeline be children of the shell and have the shell wait for all of them. |
Team-FLY |