Oberon || Library || Module Index || Search Engine || Definition || Module


Ulm's Oberon Library:
SysSignals


NAME

SysSignals - event interface for UNIX signals

SYNOPSIS

TYPE Signal = INTEGER; (* signal number: [1..nsigs-1] *)
TYPE EventType = POINTER TO EventTypeRec;
TYPE EventTypeRec =
   RECORD
      (Events.EventTypeRec)
      signo: Signal;
   END;
TYPE Event = POINTER TO EventRec;
TYPE EventRec =
   RECORD
      (Events.EventRec)
      signo: Signal;
      sigcode: INTEGER;
      sigcontext: SysTypes.UntracedAddress;
      addr: SysTypes.UntracedAddress;
      fixed: BOOLEAN;
   END;


CONST nsigs = 32; (* number of valid signals *) CONST sigHUP = 1; (* hangup *) CONST sigINT = 2; (* interrupt *) CONST sigQUIT = 3; (* quit *) CONST sigILL = 4; (* illegal instruction *) CONST sigTRAP = 5; (* trace trap *) CONST sigABRT = 6; (* used by abort, replace SIGIOT in the future *) CONST sigEMT = 7; (* EMT instruction *) CONST sigFPE = 8; (* floating point exception *) CONST sigKILL = 9; (* kill *) CONST sigBUS = 10; (* bus error *) CONST sigSEGV = 11; (* segmentation violation *) CONST sigSYS = 12; (* bad argument to system call *) CONST sigPIPE = 13; (* write on a pipe with no one to read it *) CONST sigALRM = 14; (* alarm clock *) CONST sigTERM = 15; (* software termination signal from kill *) CONST sigURG = 16; (* urgent condition on IO channel *) CONST sigSTOP = 17; (* sendable stop signal not from tty *) CONST sigTSTP = 18; (* stop signal from tty *) CONST sigCONT = 19; (* continue a stopped process *) CONST sigCHLD = 20; (* to parent on child stop or exit *) CONST sigTTIN = 21; (* to readers pgrp upon background tty read *) CONST sigTTOU = 22; (* like TTIN for output if *) CONST sigIO = 23; (* input/output possible signal *) CONST sigXCPU = 24; (* exceeded CPU time limit *) CONST sigXFSZ = 25; (* exceeded file size limit *) CONST sigVTALRM = 26; (* virtual time alarm *) CONST sigPROF = 27; (* profiling time alarm *) CONST sigWINCH = 28; (* window changed *) CONST sigLOST = 29; (* resource lost *) CONST sigUSR1 = 30; (* user defined signal 1 *) CONST sigUSR2 = 31; (* user defined signal 2 *) CONST allsigs = 32; (* number of all signals *) CONST ncodes = 1; (* number of sigcodes *)

VAR HUP INT, QUIT, ILL, TRAP, ABRT, EMT, FPE, KILL, BUS, SEGV, SYS, PIPE, ALRM, TERM, URG, STOP, TSTP, CONT, CHLD, TTIN, TTOU, IO, XCPU, XFSZ, VTALRM, PROF, WINCH, LOST, USR1, USR2: EventType;

VAR unknownSignal: Events.EventType; VAR eventType: ARRAY nsigs OF EventType; TYPE Name = ARRAY 12 OF CHAR; (* traditional name, e.g. "SIGHUP" *) VAR name: ARRAY allsigs OF Name; VAR text: ARRAY allsigs OF Events.Message; VAR codetext: ARRAY ncodes OF Events.Message;

DESCRIPTION

SysSignals initializes all signal events and defines their priority. Further SysSignals acts as event manager (see Events for details) and interfaces SYSTEM.UNIXSIGNAL.

A UNIX signal with the number signo causes eventType[signo] to be raised. A signal event contains signo (one of sigHUP..sigUSR2) and sigcode. sigcode contains some additional informations but is to be considered as very system-dependent. An example is given by the floating point exception of SysSignals.FPE: the MC68881 processor supports eight different exceptions which are all mapped to SysSignals.FPE with different sigcode values by the UNIX system.

In addition, the Sun version supports following components: sigcontext which points to a structure containing the saved registers and addr which contains the offending address in case of memory faults or similar events.

It is important to note that there are some fundamental differences between usual signal handling and event handling: With the exception of some few signals the reaction is reset to default (program termination) on receipt of a signal. The signal handler of SysSignals redeclares itself as signal handler and thus ensures that the reaction is not affected by signal receiving.

Signals have a priority like other events of Events. The priority is Priorities.interrupts for signals like SysSignals.INT, SysSignals.ALRM etc. and Priorities.fatalsignals for signals which indicate faults like SysSignals.SEGV, SysSignals.BUS, SysSignals.ILL, and SysSignals.FPE. Signals are queued on Events.func reaction if the current priority is equal or greater than the priority of the event. Event handlers for fault indicating signals must not return because this would cause re-execution of the faulting instruction and thus an infinite loop.

The component fixed may be set to TRUE if an event handler is able to fix a hard event in a way which assures that the execution may be continued without getting the same event raised again.

Signal reactions are inherited to subprocesses and in some restricted form inherited beyond exec(2). exec(2) causes all Events.funcs reactions to be reset to Events.default. Events.default and Events.ignore is inherited in both cases (fork(2)) and exec(2)). SysSignals sets the reactions during initialization to those which has been inherited: Events.default or Events.ignore. Typically SysSignals.INT and SysSignals.QUIT are ignored if the process runs in background (the shell does not wait for the process to terminate).

EXAMPLE

The following signal handler causes program termination (with ordinary cleanup):
PROCEDURE Die(event: Events.Event);
BEGIN
   SysProcess.Exit(1);
END Die;

PROCEDURE SetUp;
BEGIN
   Events.Handler(SysSignals.INT, Die);
END SetUp;

The example following demonstrates how to allow time-consuming processing to be aborted by the use of SysSignals.INT. This is very useful for interactive programs, e.g. a typical editor stops searching on SysSignals.INT.

PROCEDURE TimeConsumingProcessing(VAR completed: BOOLEAN);
   VAR newcr: SYSTEM.COROUTINE;
BEGIN
   completed := FALSE;
   SYSTEM.CRSPAWN(newcr);
   (* ... *)
   completed := TRUE;
   SYSTEM.CRSWITCH(Coroutines.source);
END TimeConsumingProcessing;

PROCEDURE CatchInterrupt(event: Events.Event);
BEGIN
   (* we assume that Setup was called by the main coroutine *)
   IF Coroutines.current # Coroutines.main THEN
      SYSTEM.CRSWITCH(Coroutines.main);
   END;
   (* SysSignals.INT has been raised outside of TimeConsumingProcessing *)
END CatchInterrupt;

PROCEDURE Setup;
   VAR completed: BOOLEAN;
BEGIN
   Events.Handler(SysSignals.INT, CatchInterrupt);
   TimeConsumingProcessing(completed);
   SYSTEM.CRSWITCH(Coroutines.source);
   IF completed THEN
      (* ordinary return of TimeConsumingProcessing *)
   ELSE
      (* TimeConsumingProcessing has been interrupted *)
   END;
END Setup;

SEE ALSO

Events
event handling
Math
defines handler for SysSignals.FPE event
SysStorage
defines handler for SysSignals.SEGV event

BUGS

Signals with default reaction cause immediate termination (without raise of termination events) when they occur.
Edited by: borchert, last change: 1996/09/17, revision: 1.6, converted to HTML: 1997/04/28

Oberon || Library || Module Index || Search Engine || Definition || Module