On Handling SIGCHLD from SBCL. Alastair Bridgewater, July, 2010. [Status: DRAFT] SIGCHLD handling via signalfd(2) requires blocking SIGCHLD permanently. Emulating a signalfd(2) requires blocking SIGCHLD from within the handler and unblocking it once the event loop has dealt with the problem child. SBCL does its own management of signals, and considers SIGCHLD to be in its "deferrable" set, which causes problems when a program needs independent control of the signal. Multiple threads screws things up, of course. Basic approach: Remove SIGCHLD from the set of signals that SBCL cares about... at runtime. Use a SIGCHLD handler written in C that runs with the SBCL "blockable" signals blocked, and does not interact directly with the Lisp heap (that is, "just" blocks SIGCHLD in the caller and writes data to whatever pipe is emulating the signalfd). For SIGCHLD this will break RUN-PROGRAM. Then again, the only two reasons to do this are writing your own RUN-PROGRAM or using ptrace(2). There is something worrisome about using ENABLE-INTERRUPT on a non-deferrable signal. Shouldn't the signal be added to the deferrable set if it's going to be run as a lisp handler? The critical fragment of code is: ;; This lies, badly, about the type of the alien variables, largely ;; due to not wanting to declare the sigset_t type. The return ;; values should probably be checked. (alien-funcall (extern-alien "sigdelset" (function int (* t) int)) (addr (extern-alien "blockable_sigset" int)) sigchld) (alien-funcall (extern-alien "sigdelset" (function int (* t) int)) (addr (extern-alien "deferrable_sigset" int)) sigchld) This fragment removes SIGCHLD from the sets of blockable and deferrable signals in the runtime. When setting up the SIGCHLD handler, the handler sigmask must be set to the blockable_sigset, lest SBCL get confused if a signal arrives while the handler is running. Conclusion: Signals are hard, let's go shopping. No, wait, that wasn't it. The signal-handling mechanics in SBCL are in need of revisiting, taking into account the various scenarios wherein a user might want to install their own signal handler. A signal does not need to be deferrable if it is masked, or the handler is set to SIG_IGN (or is SIG_DFL when the default is ignore). A signal must be deferrable if there is a lisp handler associated with it. EOF