Annotation of 43BSDReno/old/man/jobs.3j, revision 1.1

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.

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.