manual page distributed with 4.2BSD
[unix-history] / usr / src / old / man / jobs.3j
CommitLineData
8e556f67
KM
1.\" Copyright (c) 1980 Regents of the University of California.
2.\" All rights reserved. The Berkeley software License Agreement
3.\" specifies the terms and conditions for redistribution.
4.\"
5.\" @(#)jobs.3j 4.1 (Berkeley) %G%
6.\"
7.TH JOBS 3J
8.UC 4
9.SH NAME
10jobs \- summary of job control facilities
11.SH SYNOPSIS
12.nf
13.B #include <sys/ioctl.h>
14.B #include <signal.h>
15.B #include <sys/vtimes.h>
16.B #include <wait.h>
17.PP
18.B int fildes, signo;
19.B short pid, pgrp;
20.B union wait status;
21.B struct vtimes vt;
22.PP
23.B ioctl(fildes, TIOCSPGRP, &pgrp)
24.B ioctl(fildes, TIOCGPGRP, &pgrp)
25.PP
26.B setpgrp(pid, pgrp)
27.B getpgrp(pid)
28.B killpg(pgrp, signo)
29.PP
30.B sigset(signo, action)
31.B sighold(signo)
32.B sigrelse(signo)
33.B sigpause(signo)
34.B sigsys(signo, action)
35.PP
36.B wait3(&status, options, &vt)
37.PP
38.B cc ... \-ljobs
39.fi
40.SH DESCRIPTION
41The facilities described here are used to support the job control implemented
42in
43.IR csh (1),
44and may be used in other programs to provide similar facilities.
45Because these facilities are not standard in UNIX and because the
46signal mechanisms are also slightly different, the associated
47routines are not in the standard C library, but rather in the \fB\-ljobs\fR
48library.
49.PP
50For descriptions of the individual routines see the various sections listed
51in \s-2SEE ALSO\s0 below. This section attempt only to place these facilities
52in context, not to explain the semantics of the individual calls.
53.PP
54.B "Terminal arbitration mechanisms."
55.PP
56The job control mechanism works by associating with each process a number
57called a
58.I "process group";
59related processes (e.g. in a pipeline) are given the same process group.
60The system assigns a single process group number to each terminal.
61Processes running on a terminal are given read access to that terminal
62only if they are in the same process group as that terminal.
63.PP
64Thus a command interpreter may start several jobs running in different
65process groups and arbitrate access to the terminal by controlling which,
66if any, of these processes is in the same process group as the terminal.
67When a process which is not
68in the process group of the terminal tries to read from the terminal,
69all members of the process group of the process receive a SIGTTIN signal,
70which normally then causes them to stop until they are continued
71with a SIGCONT signal.
72(See
73.IR sigsys (2)
74for a description of these signals;
75.IR tty (4)
76for a description of process groups.)
77.PP
78If a process which is not in the process group of the terminal
79attempts to change the terminals mode,
80the process group of that process is sent a SIGTTOU signal, causing
81the process group to stop.
82A similar mechanism is (optionally) available for output, causing
83processes to block with SIGTTOU when they attempt to write to the terminal
84while not in its process group;
85this is controlled by the LTOSTOP bit in the tty mode
86word, enabled by \*(lqstty tostop\*(rq and disabled (the default)
87by \*(lqstty \-tostop.\*(rq
88(The LTOSTOP bit is described in
89.IR tty (4)).
90.LP
91.B "How the shell manipulates process groups."
92.PP
93A shell which is interactive first establishes its own process group
94and a process group for the terminal; this prevents other processes
95from being inadvertantly stopped while the terminal is under its control.
96The shell then assigns each job it creates a distinct process group.
97When a job is to be run in the foreground,
98the shell gives the terminal to the process group of the job using
99the TIOCSPGRP ioctl
100(See
101.IR ioctl (2)
102and
103.IR tty (4)).
104When a job stops or completes, the shell reclaims the terminal
105by resetting the terminals process group to that of the shell using
106TIOCSPGRP again.
107.PP
108Shells which are running shell scripts or running non-interactively do
109not manipulate process groups of jobs they create. Instead, they
110leave the process group of sub-processes and the terminal unchanged.
111This assures that if any sub-process they create blocks for terminal i/o,
112the shell and all its sub-processes will be blocked
113(since they are a single process group).
114The first interactive parent of the non-interactive shell
115can then be used to deal with the stoppage.
116.PP
117Processes which are orphans (whose parents have exited), and descendants
118of these processes are protected by the system from stopping, since there
119can be no interactive parent. Rather than blocking, reads from the
120control terminal return end-of-file and writes to the control
121terminal are permitted (i.e. LTOSTOP has no effect for these processes.)
122Similarly processes which ignore or hold the SIGTTIN or SIGTTOU signal are not
123sent these signals when accessing their control terminal; if they are not in the
124process group of the control terminal reads simply return end-of-file.
125Output and mode setting are also allowed.
126.PP
127Before a shell
128.I suspends
129itself, it places itself back in the process group in which it was
130created, and then sends this original group a stopping signal, stopping
131the shell and any other intermediate processes back to an interactive parent.
132The shell also restores the process group of the terminal when it finishes,
133as the process which then resumes would not necessarily be in control of
134the terminal otherwise.
135.PP
136.B "Naive processes."
137.PP
138A process which does not alter the state of the terminal,
139and which does no job control can invoke subprocesses normally
140without worry. If such a process issues a
141.IR system (3)
142call and this command is then stopped, both of the processes will stop
143together. Thus simple processes need not worry about job control, even
144if they have \*(lqshell escapes\*(rq or invoke other processes.
145.PP
146.B "Processes which modify the terminal state."
147.PP
148When first setting the terminal into an unusual mode, the process
149should check, with the stopping signals held,
150that it is in the foreground. It should then change the state of the
151terminal, and set the catches for SIGTTIN, SIGTTOU and SIGTSTP.
152The following is a sample of the code that will be needed, assuming
153that unit 2 is known to be a terminal.
154.PP
155.nf
156.ft B
157 short tpgrp;
158 \&...
159
160retry:
161 sigset(SIGTSTP, SIG_HOLD);
162 sigset(SIGTTIN, SIG_HOLD);
163 sigset(SIGTTOU, SIG_HOLD);
164 if (ioctl(2, TIOCGPGRP, &tpgrp) != 0)
165 goto nottty;
166 if (tpgrp != getpgrp(0)) { /* not in foreground */
167 sigset(SIGTTOU, SIG_DFL);
168 kill(0, SIGTTOU);
169 /* job stops here waiting for SIGCONT */
170 goto retry;
171 }
172 \fI\&...save old terminal modes and set new modes\&...\fB
173 sigset(SIGTTIN, onstop);
174 sigset(SIGTTOU, onstop);
175 sigset(SIGTSTP, onstop);
176.ft R
177.fi
178.PP
179It is necessary to ignore SIGTSTP in this code because otherwise our process
180could be moved from the foreground to the background in the middle of checking
181if it is in the foreground.
182The process holds all the stopping signals in this critical section so no other
183process in our process group can mess us up by blocking us on one of these
184signals in the middle of our check.
185(This code assumes that the command interpreter will not move a process from
186foreground to background without stopping it; if it did we would have
187no way of making the check correctly.)
188.PP
189The routine which handles the signal should clear the catch for the stop
190signal and
191.IR kill (2)
192the processes in its process group with the same signal. The statement
193after this
194.I kill
195will be executed when the process is later continued with SIGCONT.
196.PP
197Thus the code for the catch routine might look like:
198.PP
199.ft B
200.nf
201 \&...
202 sigset(SIGTSTP, onstop);
203 sigset(SIGTTIN, onstop);
204 sigset(SIGTTOU, onstop);
205 \&...
206
207onstop(signo)
208 int signo;
209{
210 \fI... restore old terminal state ...\fB
211 sigset(signo, SIG_DFL);
212 kill(0, signo);
213 /* stop here until continued */
214 sigset(signo, onstop);
215 \fI... restore our special terminal state ...\fB
216}
217.fi
218.ft R
219.PP
220This routine can also be used to simulate a stop signal.
221.PP
222If a process does not need to save and restore state when it is stopped,
223but wishes to be notified when it is continued after a stop it can catch
224the SIGCONT signal; the SIGCONT handler will be run when the process
225is continued.
226.PP
227Processes which lock data bases such as the password file should ignore
228SIGTTIN, SIGTTOU, and SIGTSTP signals while the data bases are being
229manipulated. While a process is ignoring SIGTTIN signals, reads which
230would normally have hung will return end-of-file; writes which would
231normally have caused SIGTTOU signals are instead permitted while SIGTTOU
232is ignored.
233.PP
234.B "Interrupt-level process handling."
235.PP
236Using the mechanisms of
237.IR sigset (3)
238it is possible to handle process state changes as they occur by providing
239an interrupt-handling routine for the SIGCHLD signal which occurs
240whenever the status of a child process changes. A signal handler for this
241signal is established by:
242.PP
243.RS
244.B "sigset(SIGCHLD, onchild);"
245.RE
246.LP
247The shell or other process would then await a change in child status
248with code of the form:
249.PP
250.nf
251.ft B
252recheck:
253 sighold(SIGCHLD); /* start critical section */
254 if (\fIno children to process\fB) {
255 sigpause(SIGCHLD); /* release SIGCHLD and pause */
256 goto recheck;
257 }
258 sigrelse(SIGCHLD); /* end critical region */
259 /* now have a child to process */
260.fi
261.ft R
262.PP
263Here we are using
264.IR sighold
265to temporarily block the SIGCHLD signal during the checking of the
266data structures telling us whether we have a child to process.
267If we didn't block the signal we would have a race condition since the
268signal might corrupt our decision by arriving shortly after we had
269finished checking the condition but before we paused.
270.PP
271If we need to wait for something to happen, we call
272.I sigpause
273which automically releases the hold on the SIGCHLD signal and waits for a
274signal to occur by starting a
275.IR pause (2).
276Otherwise we simply release the SIGCHLD signal and process the child.
277.I Sigpause
278is similar to the PDP-11
279.I wait
280instruction, which returns the priority of the processor to the base
281level and idles waiting for an interrupt.
282.PP
283It is important to note that the long-standing bug in the signal mechanism
284which would have lost a SIGCHLD signal which occurred while the signal
285was blocked has been fixed. This is because
286.I sighold
287uses the SIG_HOLD signal set of
288.IR sigsys (2)
289to prevent the signal action from being taken without losing the signal
290if it occurs. Similarly, a signal action set with
291.I sigset
292has the signal held while the action routine is running,
293much as a the interrupt priority of the processor is raised when
294a device interrupt is taken.
295.PP
296In this interrupt driven style of termination processing it is necessary
297that the
298.I wait
299calls used to retrieve status in the SIGCHLD signal handler not block.
300This is because a single invocation of the SIGCHLD handler may indicate
301an arbitrary number of process status changes: signals are not queued.
302This is similar to the case in a disk driver where several drives on
303a single controller may report status at once, while there is only
304one interrupt taken.
305It is even possible for no children to be ready to report status when
306the SIGCHLD handler is invoked, if the signal was posted while the SIGCHLD
307handler was active, and the child was noticed due to a SIGCHLD initially
308sent for another process.
309This causes no problem, since the handler will be called whenever there
310is work to do; the handler just has to collect all information by calling
311.I wait3
312until it says no more information is available.
313Further status changes are guaranteed to be reflected in another SIGCHLD
314handler call.
315.PP
316.B Restarting system calls.
317.PP
318In older versions of UNIX
319\*(lqslow\*(rq system calls
320were interrupted when signals occurred,
321returning EINTR.
322The new signal mechanism
323.IR sigset (3)
324normally restarts such calls
325rather than interrupting them.
326To summarize:
327.I pause
328and
329.I wait
330return error EINTR (as before),
331.I ioctl
332and
333.I wait3
334restart, and
335.I read
336and
337.I write
338restart unless some data was read or written in which case they
339return indicating how much data was read or written.
340In programs which use the older
341.IR signal (2)
342mechanisms,
343all of these calls return EINTR
344if a signal occurs during the call.
345.SH SEE ALSO
346csh(1), ioctl(2), killpg(2), setpgrp(2), sigsys(2), wait3(2), signal(3),
347tty(4)
348.SH BUGS
349The job control facilities are not available in standard version 7 UNIX.
350These facilities are still under development and may change in future
351releases of the system as better inter-process communication facilities
352and support for virtual terminals become available. The options and
353specifications of these system calls and even the calls themselves
354are thus subject to change.