From fd37652c30bdee48588cd082de0a04b95ca07472 Mon Sep 17 00:00:00 2001 From: "Kevin M. Rosenberg" Date: Mon, 8 Jan 2007 03:04:52 +0000 Subject: [PATCH] r11464: add signal handling functions --- ChangeLog | 4 +++ kmrcl.asd | 5 ++-- package.lisp | 4 +++ signals.lisp | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 signals.lisp diff --git a/ChangeLog b/ChangeLog index d3cd924..ac9dc98 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +07 Jan 2007 Kevin Rosenberg + * Version 1.93 + * signals.lisp: Add new file for signal processing + 31 Dec 2006 Kevin Rosenberg * impl.lisp, sockets.lisp, equal.lisp, datetime.lisp: Declare ignored variables diff --git a/kmrcl.asd b/kmrcl.asd index 0fab1a0..153bf6f 100644 --- a/kmrcl.asd +++ b/kmrcl.asd @@ -29,7 +29,7 @@ :maintainer "Kevin M. Rosenberg " :licence "LLGPL" :depends-on (#+sbcl sb-posix) - :components + :components ((:file "package") (:file "ifstar" :depends-on ("package")) (:file "byte-stream" :depends-on ("package")) @@ -37,7 +37,7 @@ (:file "functions" :depends-on ("macros")) (:file "lists" :depends-on ("macros")) (:file "seqs" :depends-on ("macros")) - (:file "impl" :depends-on ("macros")) + (:file "impl" :depends-on ("macros")) (:file "io" :depends-on ("macros" "impl")) (:file "console" :depends-on ("macros")) (:file "strings" :depends-on ("macros" "seqs")) @@ -58,6 +58,7 @@ (:file "listener" :depends-on ("sockets" "processes" "console")) (:file "repl" :depends-on ("listener" "strings")) (:file "os" :depends-on ("macros" "impl")) + (:file "signals" :depends-on ("package")) )) (defmethod perform ((o test-op) (c (eql (find-system 'kmrcl)))) diff --git a/package.lisp b/package.lisp index cde77c1..75d7f82 100644 --- a/package.lisp +++ b/package.lisp @@ -313,6 +313,10 @@ #:hsv255-similar #:hue-difference #:hue-difference-fixnum + + ;; signals.lisp + #:set-signal-handler + #:remove-signal-handler )) diff --git a/signals.lisp b/signals.lisp new file mode 100644 index 0000000..1547aba --- /dev/null +++ b/signals.lisp @@ -0,0 +1,70 @@ +;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; Package: modlisp -*- +;;;; ************************************************************************* +;;;; FILE IDENTIFICATION +;;;; +;;;; Name: signals.lisp +;;;; Purpose: Signal processing functions +;;;; Programmer: Kevin M. Rosenberg +;;;; Date Started: Jan 2007 +;;;; +;;;; $Id: processes.lisp 10985 2006-07-26 18:52:03Z kevin $ +;;;; ************************************************************************* + +(in-package #:kmrcl) + +(defun signal-key-to-number (sig) + "These signals and numbers are only valid on POSIX systems, perhaps +some are Linux-specific." + (case sig + (:hup 1) + (:int 2) + (:quit 3) + (:kill 9) + (:usr1 10) + (:usr2 12) + (:pipe 13) + (:alrm 14) + (:term 15) + (t + (error "Signal ~A not known." sig)))) + + +(defun set-signal-handler (sig handler) + "Sets the handler for a signal to a function. Where possible, returns +the old handler for the function for later restoration with remove-signal-handler +below. + +To be portable, signal handlers should use (&rest dummy) function signatures +and ignore the value. They should return T to tell some Lisp implementations (Allegro) +that the signal was successfully handled." + (let ((signum (etypecase sig + (integer sig) + (keyword (signal-key-to-number sig))))) + #+allegro (excl:add-signal-handler signum handler) + #+cmu (system:enable-interrupt signum handler) + #+lispworks + ;; non-documented method to get old handler, works in lispworks 5 + (let ((old-handler (when (and (boundp 'system::*signal-handler-functions*) + (typep system::*signal-handler-functions* 'array)) + (aref system::*signal-handler-functions* signum)))) + (system:set-signal-handler signum handler) + old-handler) + #+sbcl (sb-sys:enable-interrupt signum handler) + #-(or allegro cmu lispworks sbcl) (warn "Signal setting not supported on this platform.") + )) + +(defun remove-signal-handler (sig &optional old-handler) + "Removes a handler from signal. Tries, when possible, to restore old-handler." + (let ((signum (etypecase sig + (integer sig) + (keyword (signal-key-to-number sig))))) + ;; allegro automatically restores old handler, because set-signal-handler above + ;; actually pushes the new handler onto a list of handlers + #+allegro (declare (ignore old-handler)) + #+allegro (excl:remove-signal-handler signum) + #+cmu (system:enable-interrupt signum (or old-handler :default)) + ;; lispworks removes handler if old-handler is nil + #+lispworks (system:set-signal-handler signum old-handler) + #+sbcl (sb-sys:enable-interrupt signum (or old-handler :default)) + #-(or allegro cmu lispworks sbcl) (warn "Signal setting not supported on this platform.") + )) -- 2.34.1