add-signal-handler

$Revision: 5.0.2.4 $

Function

Package: EXCL

Arguments: (number function)

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. 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. Signals handlers should return a non-nil value if they handle the signal, so that other, nested handlers are are not invoked to handle the signal. A signal that is posted during a gc is processed immediately after the gc finishes.

Here is an example 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 is not handled at all can be caught.
;; 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:defforeign 'unix-signal
	       :entry-point (ff:convert-to-lang "signal")
	       :arguments '(integer integer))
	   (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:defforeign 'getpid)
t
user(5): (ff:defforeign 'kill :arguments '(integer integer))
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 also set-signal-handler, remove-signal-handler, *signals*, and with-signal-handler.

The general documentation description is in introduction.htm. The index is in index.htm.

Copyright (C) 1998-1999, Franz Inc., Berkeley, CA. All Rights Reserved.