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.234A 
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.