This section only applies to UNIX as signals are not used under Windows.
Prolog sets up signal handlers when either QP_initialize()
or QP_toplevel()
is called. These handlers provide the default
interrupt handling for ^c described in the
previous sections. QP_initialize()
and QP_toplevel()
sets handlers for all signals that have the default
handler and the default behavior is not what Prolog wants.
If users have set their own signal handlers (which are
different from the default signal handlers) then Prolog
will not change these handlers. Once Prolog has started up
and is running the toplevel read-prove loop, Prolog will not
change any signal handlers unless the user calls QP_toplevel()
.
Users can set and remove signal handlers using the system
function signal(2)
.
To set up a signal handler, call the routine
signal(signal_name, function_name)
from within a C foreign function, where signal_name is a constant
identifying the signal being trapped and function_name is the name
of the function to be called in the event of the signal. The
constants identifying the various signals are defined in the file
/usr/include/signal.h
.
The example below shows how one would define an interrupt handler using
signal
and QP_action()
. For most users ^C is the interrupt
character. The files
interrupt.c
and interrupt.pl
make up this example; the interrupt handler
is set up
by calling establish_handler/0
after compiling interrupt.pl
.
interrupt.pl/* This is the foreign interface file for a sample interrupt handler. */ foreign_file('interrupt',[establish_handler]). foreign(establish_handler, establish_handler). :- load_foreign_files(['interrupt'], []).
interrupt.c/* The function my_handler is called when the user types the interrupt character (normally ^c). This function prompts for a response and executes the user's choice. */ #include <signal.h> #include <quintus/quintus.h> int my_handler() { char c; for(;;) { printf("\nWell? "); c = getchar(); if (c != '\n') while (getchar() != '\n') {}; switch(c) { case 'a': QP_action(QP_ABORT); case 'e': QP_action(QP_EXIT); case 'c': return; default: printf("a, c or e, please"); } } } void establish_handler() { signal(SIGINT, my_handler); }
The following trace illustrates the use of these files:
% cc -c interrupt.c % prolog Quintus Prolog Release 3.5 (Sun 4, SunOS 5.5) | ?- compile(interrupt). % compiling file /goedel/tim/interrupt.pl % foreign file /goedel/tim/interrupt.o loaded % interrupt.pl compiled in module user, 0.150 sec 1,508 bytes yes | ?- establish_handler. yes | ?- write(hi). hi yes | ?- ^C Well? g a, c or e, please Well? a ! Execution aborted | ?- ^C Well? e %