From eb6854f6d9d6dfe661ec52656cb1e4f75166375d Mon Sep 17 00:00:00 2001 From: Marius Gerbershagen Date: Fri, 15 Feb 2019 22:53:38 +0100 Subject: [PATCH 1/2] doc: document unix signal handling capabilities --- src/doc/manual/extensions/signals.txi | 78 +++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/src/doc/manual/extensions/signals.txi b/src/doc/manual/extensions/signals.txi index 38ee1c0f7..507bb6338 100644 --- a/src/doc/manual/extensions/signals.txi +++ b/src/doc/manual/extensions/signals.txi @@ -108,6 +108,7 @@ The other option is to let ECL handle signals itself. This would be safer when t @node Signals and Interrupts - Signals Reference @subsection Signals Reference + @lspindex mp:with-interrupts @lspindex mp:without-interrupts @@ -152,3 +153,80 @@ Care must be taken not to let either @code{mp:allow-with-interrupts} or @code{mp @end lisp @end defmac + + +@lspindex ext:unix-signal-received +@deftp Condition ext:unix-signal-received +Unix signal condition + +@subsubheading Class Precedence List +@code{condition, t} + +@subsubheading Methods +@lspindex ext:unix-signal-received-code +@defun ext:unix-signal-received-code condition +Returns the signal code of @code{condition} +@end defun +@end deftp + +@lspindex ext:get-signal-handler +@defun ext:get-signal-handler code +Queries the currently active signal handler for @var{code}. +@end defun + +@lspindex ext:set-signal-handler +@defun ext:set-signal-handler code handler +Arranges for the signal @var{code} to be caught in all threads and +sets the signal handler for it. The value of @var{handler} modifies +the signal handling behaviour as follows: +@table @asis +@item @var{handler} is a function designator +The function designated by @var{handler} will be invoked with no +arguments +@item @var{handler} is a symbol denoting a condition type +A continuable error of the given type will be signaled +@item @var{handler} is equal to @var{code} +A condition of type @code{ext:unix-signal-received} with the +corresponding signal code will be signaled +@item @var{handler} is @code{nil} +The signal will be caught but no handler will be called +@end table +@end defun + +@lspindex ext:catch-signal +@defun ext:catch-signal code flag &key process +Changes the action taken on receiving the signal @var{code}. +@var{flag} can be one of the following: +@table @asis +@item @code{nil} or @code{:ignore} +Ignore the signal +@item @code{:default} +Use the default signal handling strategy of the operating system +@item @code{t} or @code{:catch} +Catch the signal and invoke the signal handler as given by @code{ext:get-signal-handler} +@item @code{:mask}, @code{:unmask} +Change the signal mask of either a) the not yet enabled @var{process} +or b) the current process, if @var{process} is not supplied +@end table +Returns @code{t} on success and @code{nil} on failure. +@end defun + +@exindex Setting a signal handler +Example: +@lisp +CL-USER> (ext:catch-signal ext:+SIGPIPE+ :catch) +T +CL-USER> (ext:get-signal-handler ext:+SIGPIPE+) +NIL +CL-USER> (ext:set-signal-handler ext:+SIGPIPE+ + #'(lambda () + (format t "SIGPIPE detected in process: ~a~%" process))) +# +@end lisp +Passing the SIGPIPE signal to the ECL program with @code{killall -s +SIGPIPE ecl} results in the output: +@example +@verbatim +SIGPIPE detected in process: # +@end verbatim +@end example From c5d2408cc532000e6bd5fa27d6e23adf8011cc77 Mon Sep 17 00:00:00 2001 From: Marius Gerbershagen Date: Wed, 20 Feb 2019 21:51:28 +0100 Subject: [PATCH 2/2] be consistent with the arguments passed to signal handlers The :process keyword argument is used inconsistently for symbols denoting functions and function objects. Furthermore, it isn't needed and unused in our own code. --- src/c/unixint.d | 12 ++++-------- src/lsp/top.lsp | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/c/unixint.d b/src/c/unixint.d index 1b7b74b2c..4c5256ab7 100644 --- a/src/c/unixint.d +++ b/src/c/unixint.d @@ -337,15 +337,11 @@ handle_signal_now(cl_object signal_code, cl_object process) * be a function, a symbol denoting a function or * a symbol denoting a condition. */ - if (cl_find_class(2, signal_code, ECL_NIL) != ECL_NIL) + if (cl_find_class(2, signal_code, ECL_NIL) != ECL_NIL) { cl_cerror(2, str_ignore_signal, signal_code); -#ifdef ECL_THREADS - else if (!Null(process)) - _ecl_funcall3(signal_code, @':process', process); -#endif - else - _ecl_funcall1(signal_code); - break; + break; + } + /* fallthrough */ case t_cfun: case t_cfunfixed: case t_cclosure: diff --git a/src/lsp/top.lsp b/src/lsp/top.lsp index d0aabb267..c070d28f0 100644 --- a/src/lsp/top.lsp +++ b/src/lsp/top.lsp @@ -513,7 +513,7 @@ Use special code 0 to cancel this operation.") (restart-case (simple-terminal-interrupt) (continue ()))) -(defun terminal-interrupt (&key process (correctablep t)) +(defun terminal-interrupt (&key (correctablep t)) (declare (ignore correctablep)) #+threads (mp:without-interrupts