FunctionPackage: exclToCDocOverviewCGDocRelNotesFAQIndexPermutedIndex
Allegro CL version 10.1
Unrevised from 10.0 to 10.1.
10.0 version

add-signal-handler

Arguments: number function &key delay-interrupts

function is added as a signal handler for signal number.

The handling of operating system dependent signals generated during program execution is not part of Common Lisp. A signal is a small integer. The list of valid signals is given in a system dependent file, usually on UNIX something like /usr/include/signals.h. Signals are either synchronous or asynchronous, but there is no distinction made in this interface--the handling of both types of signals is the same. Such signals are attached at the unix level to foreign functions gotsig and syncsig1, respectively, if they are normally handled by the Lisp, via the UNIX signal() function. Other signals are not so attached, and will either perform some default UNIX action, or some action unrelated to Lisp operation.

Users adding code to handle UNIX signals should use the foreign function lisp_signal() rather than signal(). lisp_signal() (supplied by Franz), which does the right and safe thing with signals. Note lisp_signal() is used in the example below. (Some earlier versions of this documentation had a call to signal() in that example. On many platforms, it does not make a difference but on some it does.)

At the Lisp level, a handler for a signal is a function of two arguments, signal number and t. If there is no handler for a particular signal, then some default action is invoked, which is usually to signal an error. Signal handlers should return a true value if they handle the signal, so that other, nested handlers are not invoked to handle the signal. A signal that is posted during a gc is processed immediately after the gc finishes.

Be warned that once a programmer starts dealing with the signal interface at the operating system level, the effects might be far reaching and unintended. Please consider contacting Franz Inc. Technical Support before proceeding to do so. Further, such low-level modifications to signal handling could be non-portable across UNIX platforms, could break existing usages of signals by Allegro CL and thus affect its operation, or it could break existing usages of other systems running along with Allegro CL.

If the delay-interrupts arguemnt is true, then the handler be run in a with-delayed-interrupts, else it will be run with interrupts enabled.

Here is an example of adding a signal handler from a UNIX machine:

user(16): (defun foo (signal &optional ignore)
	   (format t "~&; got signal ~d~%" signal)
	   t)
foo
user(17): (add-signal-handler 2 'foo)
((2 . foo) (14 . mp::sigalrm-handler))
user(18):        <<<< Control-C was typed here at this prompt
; got signal 2
user(18):
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Now, we show how a signal that has not yet been attached at the UNIX
;; level to either gotsig or syncsig1 can be so attached, so that
;; add-signal-handler will have an effect at the lisp level.  It is the
;; programmer's responsibiluty to take care that the signal number is
;; not already attached to some conflicting Unix signal handling function.
;; Although the foreign function interface is used, no foreign
;; files need to be loaded.
;;  Define a function SETUP-FOR-NEW-SIGNAL
user(1): (let ((gotsig-address
		(ff:get-entry-point (ff:convert-to-lang "gotsig"))))
	   (unless gotsig-address
	     (error "couldn't find address of gotsig"))
	   (ff:def-foreign-call (unix-signal "lisp_signal") 
                                (signal old-handler))
	   (defun setup-for-new-signal (number)
	     (unix-signal number gotsig-address)))
setup-for-new-signal
;;  Define a constant holding our new signal number.
user(2): (defconstant *additional-signal* 30
	   "This is the signal number of the signal we want to catch.")
*additional-signal*
;;  The lisp function that handles the signal
user(3): (defun additional-signal-handler (signal &optional ignore)
	   (format t "additional-signal-handler: ~s~%" signal)
	   (finish-output)
	   t)
additional-signal-handler
;;  Now we generate a test signal
user(4): (ff:def-foreign-call getpid (:void))
t
user(5): (ff:def-foreign-call kill (pid signal))
t
;;  Tell the system about the new signal
user(6): (setup-for-new-signal *additional-signal*)
0
;;  Send the signal, and notice that the debugger handles it
user(7): (kill (getpid) 30)
Error: Received signal number 30 (user defined signal 1)
  [condition type: simple-break]
Restart actions (select using :continue):
 0: continue computation
[1c] user(8): :pop
;;  Have our handler added...
user(9): (add-signal-handler *additional-signal* 'additional-signal-handler)
((30 . additional-signal-handler) (14 . mp::sigalrm-handler))
;;  ...and try it again
user(10): (kill (getpid) 30)
additional-signal-handler: 30          ;; <<< our function handles it
0
user(11):

See with-signal-handler, set-signal-handler, *signals*, and remove-signal-handler


Copyright (c) 1998-2022, Franz Inc. Lafayette, CA., USA. All rights reserved.
This page was not revised from the 10.0 page.
Created 2019.8.20.

ToCDocOverviewCGDocRelNotesFAQIndexPermutedIndex
Allegro CL version 10.1
Unrevised from 10.0 to 10.1.
10.0 version