This subsection describes the procedures for sending signals to other processes and for handling signals. It also enumerates all the possible signals and their default behavior.
TYPE SignalOrNone = (SigNone, SigHUp, SigInt, SigQuit, SigIll, SigTrap, SigIOT, SigEMT, SigFPE, SigKill, SigBus, SigSegV, SigSys, SigPipe, SigAlrm, SigTerm, SigUrg, SigStop, SigTStp, SigCont, SigChld, SigTTIn, SigTTOu, SigIO, SigXCPU, SigXFSz, SigVTAlrm, SigProf, SigWinCh, Sig29, SigUsr1, SigUsr2); Signal = [SigHUp .. SigUsr2];
SignalOrNone enumerates the names of all the signals; there are 31 different named signals (not including SigNone). The definition of Signal is consistent with the numbering of signals in Ultrix 1.1 and 2.0 (see sigvec(2)). However, many of these signals should not be used by OS clients because OS provides different mechanisms for dealing with the underlying conditions. It is highly recommended that only the following signals be used:
Send | Handle | ||
Name | ok? | ok? | Usage |
SigHUp | No | Yes | Modem carrier has dropped |
SigInt | Yes | Yes | User changed his mind (Control-C) |
SigQuit | Yes | Yes | User wants core image (Control-\) |
SigKill | Yes | No | Unconditional termination |
SigTerm | Yes | Yes | General software termination signal |
SigStop | Yes | No | Unconditional stop |
SigTStp | Yes | Yes | User wants to stop (Control-Z) |
SigCont | Yes | Yes | Restart stopped process |
SigTTIn | No | Yes | Read by background process |
SigTTOu | No | Yes | Write by background process |
SigUsr1 | Yes | Yes | User-defined signal (System V) |
SigUsr2 | Yes | Yes | User-defined signal (System V) |
Topaz converts hardware traps to exceptions defined in the System and Trap interfaces rather than converting them to the signals SigIll, SigIOT, SigEMT, SigFPE, SigBus, and SigSegV, as Ultrix does. Topaz reserves the hardware breakpoint trap for the debugger rather than converting it to SigTrace. OS raises exceptions for the synchronous events that Ultrix converts to the signals SigSys and SigPipe. OS doesn't provide the Ultrix interval timing facilities that send SigAlrm, SigVTAlrm, and SigProf; instead clients can program their own facilities using the Thread and Time interfaces. OS doesn't send SigChld or SigIO because a client can fork an extra thread to wait for the event (child state change or asynchronous I/O); this will apply to SigUrg if sockets are implemented. OS doesn't provide the Ultrix resource limit facilities that send SigXCPU and SigXFSz. OS doesn't provide the Ultrix 2.0 window size change feature that sends SigWinCh. Sig29 is reserved for future standardization.
PROCEDURE SendSignal( pid: PID; signal: SignalOrNone; euser: User := NIL) RAISES {Error}; (* NotSuperUserEC, BadPIDEC, NotOwnerEC *) PROCEDURE SendSignalToGroup( pgrp: PGRP; signal: SignalOrNone; euser: User := NIL) RAISES {Error}; (* NotSuperUserEC, BadPIDEC, NotOwnerEC *)
SendSignal sends a signal to the process with a specified process identifier; specifying pid equal to NullPID means to use the process identifier of the calling process. (Note that the conventions obeyed by the Ultrix kill kernel call for a pid of 0 or -1 do not apply to SendSignal.) SendSignalToGroup sends a signal to all the processes in a specified process group; specifying a process group identifier equal to NullPID means to send to all the processes in the group of the calling process (including the calling process itself).
Sending SigNone is a way to check the validity of a process identifier: normal error checking is done, but no signal is actually sent.
The sender and receiver must have the same effective user name, unless either the sender is the super-user, or the signal is SigCont and the sender is an ancestor of the receiver. NotOwnerEC is raised if none of these conditions are satisfied.
BadPIDEC is raised if no process has the process identifier passed to SendSignal or the process group identifier passed to SendToGroup.
SendSignal and SendSignalToGroup interpret the euser parameter the same way Open does.
TYPE SignalState = (SignalDefault, SignalIgnore, SignalHandle);
A signal state represents the intention by a process with respect to a particular signal to handle the signal, to ignore the signal, or to accept the default action for that signal.
PROCEDURE SetMySignalState( signal: Signal; state: SignalState) : SignalState RAISES {Error} (* BadStateForSignalEC *);
SetMySignalState allows a process to declare its intention with respect to a specified signal. It returns the previous intention.
SetMySignalState raises BadStateForSignalEC if an attempt is made to handle or ignore a signal other than SigHUp, SigInt, SigQuit, SigPipe, SigTerm, SigTStp, SigCont, SigTTIn, SigTTOu, SigXCPU, SigWinCh, Sig29, SigUsr1, or SigUsr2. It raises BadStateForSignalEC if an attempt is made to ignore SigCont. Requiring SigKill and SigStop to be defaulted provides a reliable way to terminate or stop an errant process. Disallowing SigCont to be ignored ensures that a stopped process can be continued.
As mentioned in Section 2.9, page , there
are several possible default actions that can occur when a signal arrives
for a process and the signal state is SignalDefault: to ignore the signal,
to stop execution of the process temporarily, to continue execution of the
process after such a temporary stop, or to terminate the process. If a
signal is ignored (either because the signal state is SignalIgnore or
because the signal state is SignalDefault and the default action for that
signal is to ignore it), it is as if the signal had never been sent.
Stopping and continuing processes is discussed in Section 2.11, page
. Terminating processes is discussed in Section 5.4,
page
.
Which of the default actions actually occurs depends on the identity of the signal:
There is a special case involving the stop signals: if a process is an
orphan, then only SigStop will stop it; the default action for SigTStp,
SigTTIn, and SigTTOu is to terminate the process. The reason for this is
that in the typical usage of stop signals in conjunction with job control,
it is up to the parent to continue a stopped child (see Section
2.11, page ). An orphan would be stopped forever,
so it is terminated instead.
It should be noted that signal states are inherently of process-wide significance. It is up to the application to provide its own synchronization if it dynamically alters signal state settings.
TYPE Signals = BITS 32 FOR SET OF Signal; CONST AllSignals = Signals{SigHUp .. SigUsr2}; PROCEDURE WaitForSignal(allowed: Signals): Signal RAISES {Error, Alerted}; (* BadStateForSignalEC *)
WaitForSignal waits until one of the signals in the allowed set becomes pending (by being sent to this process), then makes the signal not pending and returns its identity. If several signals in the allowed set are pending, it is unpredictable which of them WaitForSignal will choose. Similarly if a signal becomes pending and that signal is in the allowed sets of several threads that have called WaitForSignal, it is unpredictable which thread will be unblocked. WaitForSignal raises BadStateForSignalEC if any signal in the allowed set is not in the state SignalHandle, since it could never become pending. WaitForSignal is alertable.
Ultrix note: The priority of the thread calling WaitForSignal must be higher than that of any compute-bound thread. See GetPriority and SetPriority in the ThreadFriends interface.
Taos note: Since the Firefly thread scheduler implements time-slicing, the priority of the thread calling WaitForSignal must be at least as high as that of any compute-bound thread.