KMRCLを眺める(232) SET-SIGNAL-HANDLER — #:g1

Posted 2011-01-05 10:54:00 GMT

今回はKMRCLのsignals.lispから、SET-SIGNAL-HANDLERです。
処理系依存で処理系に送られたシグナルをハンドリングする機能があるようですが、それをポータブルに書けるようにしたもののようです。
定義は、

(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) #+(and lispworks unix) ;; 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 (and lispworks unix) sbcl) (declare (ignore sig handler)) #-(or allegro cmu (and lispworks unix) sbcl) (warn "Signal setting not supported on this platform.")))

となっていて前回のSIGNAL-KEY-TO-NUMBERが内部で使われています。
長いですが、それぞれの処理系で実質2、3行といったところです。
動作は、
;; USR1へのハンドラを設定
(kl:set-signal-handler :usr1 
                       (lambda (&rest args)
                         (declare (ignore args))
                         (princ "Hello USR1 !")
                         (terpri)
                         (force-output)))
;; プロセスIDを確認
(kl:getpid)
;=> 6269

他のシェル等から $ kill -USR1 6269

;; 処理系が起動しているターミナル等に表示される筈 * Hello USR1 !

というところ

comments powered by Disqus