User-specified signal handlers

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
     %