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.
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().
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();
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.
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.