Path: utzoo!attcan!uunet!cs.utexas.edu!tut.cis.ohio-state.edu!cica!iuvax!purdue!haven!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.unix.questions Subject: Re: SYS V SIGCLD Handling Message-ID: <20871@mimsy.umd.edu> Date: 21 Nov 89 21:57:27 GMT References: <957@sdrc.UUCP> <1989Nov20.124459.26023@virtech.uucp> <1989Nov21.132942.29972@virtech.uucp> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 56 In article <1989Nov21.132942.29972@virtech.uucp> cpcahil@virtech.uucp (Conor P. Cahill) writes: >The documentation states that SIGCLDs received while a process is in the >SIGCLD signal handler will be ignored. That sounds like you could miss >a SIGCLD or two. The documentation (almost) lies. SIGCLD is, in System V, not a signal. Oh, it has a signal number, and can be generated by kill(2), and can be caught by signal(2), and so forth. But it is not a signal. It is a weird thing that happens to use some of the existing signal code so as to avoid inventing a new facility, while at the same time being very un-signal-like in its behaviour. (Just like SIGCONT in BSD, actually....) >In testing, I found that while the SIGCLD is ignored in the signal handler, >once the handler executes signal(SIGCLD,handler), if there are any child >processes that have exited and have not yet been waited for, another SIGCLD >is generated. Right. Unlike all other signals, SIGCLD is `regenerative.' (It is NOT queued, despite reports of claims to that effect in other parts of System V documentation.) Instead, there is special code in the signal() system call to check to see if the action for SIGCLD is being altered. If so, one of the following is true: a) SIGCLD is being set to SIG_IGN. In this case, all zombie (exited) children of the current process are flushed as if by a series of calls to wait(2). b) SIGCLD is being set to SIG_DFL. In this case, do nothing. c) SIGCLD is being set to a catch function. In this case, one (1) SIGCLD signal is immediately posted (via psignal(), if the kernel function has the same name as the one in BSD). Meanwhile, there is a second special case in the kernel, in exit(): If u.u_signal[SIGCLD]==SIG_IGN, the newly dead process is discarded immediately. Otherwise, a SIGCLD signal is sent (possibly optional on u.u_signal[SIGCLD]!=SIG_DFL---this would simply be an optimisation). There is no third special case. *All* signals are reset to SIG_DFL on actual delivery, including SIGCLD. Thus, the `proper' way to catch SIGCLD in SysV is: void catch(int sig) { int w, status; do { w = wait(&status); } while (w==-1 && errno==INTR); <<< do something with w and status >>> (void) signal(SIGCLD, catch);/* recurses if necessary */ } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris