SWI-Prolog offers both a C and Prolog interface to deal with software
interrupts (signals). The Prolog mapping is defined in
section 4.12. This
subsection deals with handling signals from C.
If a signal is not used by Prolog and the handler does not call
Prolog in any way, the native signal interface routines may be used.
Any handler that wishes to call one of the Prolog interface functions
should call PL_sigaction()
to install the handler. PL_signal()
provides a deprecated interface that is notably not capable of properly
restoring the old signal status if the signal was previously handled by
Prolog.
- int PL_sigaction(int
sig, pl_sigaction_t *act, pl_sigaction_t *oldact)
- Install or query the status for signal sig. The signal is an
integer between 1 and 64, where the where the signals up to 32 are
mapped to OS signals and signals above that are handled by Prolog's
synchronous signal handling. The
pl_sigaction_t
is a struct
with the following definition:
typedef struct pl_sigaction
{ void (*sa_cfunction)(int); /* traditional C function */
predicate_t sa_predicate; /* call a predicate */
int sa_flags; /* additional flags */
} pl_sigaction_t;
The sa_flags
is a bitwise or of PLSIG_THROW
,
PLSIG_SYNC
and PLSIG_NOFRAME
. Signal handling
is enabled if PLSIG_THROW
is provided, sa_cfunction
or
sa_predicate
is provided. sa_predicate
is a
predicate handle for a predicate with arity 1. If no action is
provided the signal handling for this signal is restored to the default
before
PL_initialise()
was called.
Finally, 0 (zero) may be passed for sig. In that case the
system allocates a free signal in the Prolog range (32 ... 64).
Such signal handler are activated using PL_thread_raise().
- void (*)() PL_signal(sig,
func)
- This function is equivalent to the BSD-Unix signal() function,
regardless of the platform used. The signal handler is blocked while the
signal routine is active, and automatically reactivated after the
handler returns.
After a signal handler is registered using this function, the native
signal interface redirects the signal to a generic signal handler inside
SWI-Prolog. This generic handler validates the environment, creates a
suitable environment for calling the interface functions described in
this chapter and finally calls the registered user-handler.
By default, signals are handled asynchronously (i.e., at the time
they arrive). It is inherently dangerous to call extensive code
fragments, and especially exception related code from asynchronous
handlers. The interface allows for synchronous handling of
signals. In this case the native OS handler just schedules the signal
using PL_raise(),
which is checked by PL_handle_signals()
at the call- and redo-port. This behaviour is realised by or-ing sig
with the constant
PL_SIGSYNC
.233A
better default would be to use synchronous handling, but this interface
preserves backward compatibility.
Signal handling routines may raise exceptions using
PL_raise_exception().
The use of PL_throw()
is not safe. If a synchronous handler raises an exception, the exception
is delayed to the next call to PL_handle_signals();
- bool PL_raise(int
sig)
- Register sig for synchronous handling by Prolog.
Synchronous signals are handled at the call-port or if foreign code
calls PL_handle_signals().
See also thread_signal/2.
- int PL_handle_signals(void)
- Handle any signals pending from PL_raise(). PL_handle_signals()
is called at each pass through the call- and redo-port at a safe point.
Exceptions raised by the handler using PL_raise_exception()
are properly passed to the environment.
The user may call this function inside long-running foreign functions
to handle scheduled interrupts. This routine returns the number of
signals handled. If a handler raises an exception, the return value is
-1 and the calling routine should return with FALSE
as soon
as possible.
- int PL_get_signum_ex(term_t
t, int *sig)
- Extract a signal specification from a Prolog term and store as an
integer signal number in sig. The specification is an
integer, a lowercase signal name without
SIG
or the full
signal name. These refer to the same: 9
, kill
and SIGKILL
. Leaves a typed, domain or instantiation error
if the conversion fails.