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