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.