Schedule an alarm signal
alarm (UInt_Type secs [, Ref_Type secs_remaining])
The alarm
function schedules the delivery of a SIGALRM
signal in secs
seconds. Any previously scheduled alarm will
be canceled. If secs
is zero, then no new alarm will be
scheduled. If the second argument is present, then it must be a
reference to a variable whose value will be set upon return to the
number of seconds remaining for a previously scheduled alarm to take
place.
This example demonstrates how the alarm
function may be
used to read from stdin
within a specified amount of time:
define sigalrm_handler (sig)
{
throw ReadError, "Read timed out";
}
define read_or_timeout (secs)
{
variable line, err;
signal (SIGALRM, &sigalrm_handler);
() = fputs ("Enter some text> ", stdout); () = fflush (stdout);
alarm (secs);
try (err)
{
if (-1 == fgets (&line, stdin))
throw ReadError, "Failed to read from stdin";
}
catch IOError:
{
message (err.message);
return NULL;
}
return line;
}
Some operating systems may implement the sleep
function using
alarm
. As a result, it is not a good idea to mix calls to
alarm
and sleep
.
The default action for SIGALRM
is to terminate the process.
Hence, if alarm
is called it is wise to establish a signal
handler for SIGALRM
.
Get the value of an interval timer
(secs, period) = getitimer (Int_Type timer)
This function returns the value of the specified interval timer as a
pair of double precision values: period
and secs
.
The value of secs
indicates the number of seconds
remaining before the timer expires. A value of 0 for
secs
indicates that the timer is inactive.
The value of period
indicates the periodicity of the timer.
That is, when the timer goes off, it will automatically be reset to
go off again after period
seconds.
There are 3 interval timers available: ITIMER_REAL
,
ITIMER_VIRTUAL
, and ITIMER_PROF
.
The ITIMER_REAL
timer operates in real time and when the time
elapses, a SIGALRM
will be sent to the process.
The ITIMER_VIRTUAL
timer operates in the virtual time of the
process; that is, when process is actively running. When it
elapses, SIGVTALRM
will be sent to the process.
The ITIMER_PROF
operates when the process is actively
running, or when the kernel is performing a task on behalf of the
process. It sends a SIGPROF
signal to the process.
The interaction between these timers and the sleep
and
alarm
functions is OS dependent.
The resolution of a timer is system dependent; typical values are on the order of milliseconds.
Set the value of an interval timer
setitimer (Int_Type timer, secs [, period] [,&old_secs, &old_period])
This function sets the value of a specified interval timer, and
optionally returns the previous value. The value of the
timer
argument must be one of the 3 interval timers
ITIMER_REAL
, ITIMER_VIRTUAL
, or ITIMER_PROF
.
See the documentation for the getitimer
function for
information about the semantics of these timers.
The value of the secs
parameter specifies the expiration time
for the timer. If this value is 0, the timer will be disabled.
Unless a non-zero value for the optional period
parameter is
given, the timer will be disabled after it expires. Otherwise,
the timer will reset to go off with a period of period
seconds.
The final two optional arguments are references to variables that will be set to the previous values associated with the timer.
Establish a signal handler
signal (Int_Type sig, Ref_Type func [,Ref_Type old_func])
The signal
function assigns the signal handler represented by
func
to the signal sig
. Here func
is usually
reference to a function that takes an integer argument (the signal)
and returns nothing, e.g.,
define signal_handler (sig)
{
return;
}
Alternatively, func
may be given by one of the symbolic
constants SIG_IGN
or SIG_DFL
to indicate that the
signal is to be ignored or given its default action, respectively.
The first parameter, sig
, specifies the signal to be handled.
The actual supported values vary with the OS. Common values on Unix
include SIGHUP
, SIGINT
, and SIGTERM
.
If a third argument is present, then it must be a reference to a variable whose value will be set to the value of the previously installed handler.
This example establishes a handler for SIGTSTP
.
static define sig_suspend (); % forward declaration
static define sig_suspend (sig)
{
message ("SIGTSTP received-- stopping");
signal (sig, SIG_DFL);
() = kill (getpid(), SIGSTOP);
message ("Resuming");
signal (sig, &sig_suspend);
}
signal (SIGTSTP, &sig_suspend);
Currently the signal interface is supported only on systems that implement signals according to the POSIX standard.
Once a signal has been received, it will remain blocked until after
the signal handler has completed. This is the reason SIGSTOP
was used in the above signal handler instead of SIGTSTP
.
Change the list of currently blocked signals
sigprocmask (Int_Type how, Array_Type mask [,Ref_Type old_mask])
The sigprocmask
function may be used to change the list of
signals that are currently blocked. The first parameter indicates
how this is accomplished. Specifically, how
must be one of
the following values: SIG_BLOCK
, SIG_UNBLOCK
, or
SIG_SETMASK
.
If how
is SIG_BLOCK
, then the set of blocked signals
will be the union the current set with the values specified in the
mask
argument.
If how
is SIG_UNBLOCK
, then the signals specified by
the mask
parameter will be removed from the currently blocked
set.
If how
is SIG_SETMASK
, then the set of blocked signals
will be set to those given by the mask
.
If a third argument is present, then it must be a reference to a variable whose value will be set to the previous signal mask.
Suspend the process until a signal is delivered
sigsuspend ([Array_Type signal_mask])
The sigsuspend
function suspends the current process
until a signal is received. An optional array argument may be
passed to the function to specify a list of signals that should be
temporarily blocked while waiting for a signal.
The following example pauses the current process for 10 seconds
while blocking the SIGHUP
and SIGINT
signals.
static variable Tripped;
define sigalrm_handler (sig)
{
Tripped = 1;
}
signal (SIGALRM, &sigalrm_handler);
Tripped = 0;
alarm (10);
while (Tripped == 0) sigsuspend ([SIGHUP, SIGINT]);
Note that in this example the call to sigsuspend
was wrapped in
a while-loop. This was necessary because there is no guarantee that
another signal would not cause sigsuspend
to return.