Re: wait(2) and SIGCHLD
Date:Fri, 14 Aug 2020 20:01:18 +0200 From:Edgar =?iso-8859-1?B?RnXf?= Message-ID: <20200814180117.gq61...@trav.math.uni-bonn.de> | 3. I don't see where POSIX defines or allows this, but given 2., I'm surely |missing something. Actually, I did go take a look, it is in the XSH page for _Exit() under "Consequences of Process Termination" (some other places reference this section). kre
Re: wait(2) and SIGCHLD
Date:Fri, 14 Aug 2020 20:01:18 +0200 From:Edgar =?iso-8859-1?B?RnXf?= Message-ID: <20200814180117.gq61...@trav.math.uni-bonn.de> | 3. I don't see where POSIX defines or allows this, but given 2., I'm surely |missing something. It is specified to work this way in POSIX, though right now I don't have the time to go dig out exactly where. Setting SIGCHLD to SIG_IGN effectively means that you want to ignore your children - they then don't report any exit status to their parent, but simply vanish when they exit. Thus when the parent does a wait() it has no children, and gets ECHLD. Leave (or set) SIGCHLD to SIG_DFL and you don't get signals, but child processes do report status to their parent. Catch SIGCHLD and you'll get signalled when a child exits (I'm not sure if NetBSD guarantees one signal delivery for each exited child or just a signal if there are some unspecified number of exited children). The actions on an ignored SIGCHLD is SysV inherited behaviour, Bell Labs (v7/32V) and CSRG BSD systems didn't act this way. kre
Re: wait(2) and SIGCHLD
> What I observe is that a process that explicitly ignores SIGCHLD > (SIG_IGN), then forks a child which exits, when wait()ing for the > child, gets ECHILD (i.e., wait returns -1 and errno is ECHILD). And the ECHILD return is delayed until all children have terminated (ie, until there are no outstanding children, until the ECHILD return is accurate). That's important for some use cases. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: wait(2) and SIGCHLD
hello. I think Mouse said it best. There is a difference between SIG_DFL and SIG_IGN, which is how you can not get signaled when a child exists, but wait(2) will still wait for a child if you call it. Hope that helps. -Brian On Aug 14, 10:10am, Brian Buhrow wrote: } Subject: Re: wait(2) and SIGCHLD } Hello. I'm not sure I've completely understood your question, but I } think you're confusing the issue of whether a child posts a SIGCHLD signal } when it exits versus whether the current process that's calling wait(2) } receives a SIGCHLD when a child exits. The default behavior, as I } understand it, is that if a process has children, by default, it will not } get signaled if those children terminate. However, if that process then } calls wait(2), it will hang until a child terminates, regardless of whether } it's configured to receive the SIGCHLD or not. In that instance, I think } the man page is wrong, at least if code I have running is to be believed. So, } I think there's no difference between the default ignoring of the SIGCHLD } signal and explicitly ignoring it. } -Brian } } On Aug 14, 1:51pm, Edgar =?iso-8859-1?B?RnXf?= wrote: } } Subject: wait(2) and SIGCHLD } } I'm confused regarding the behaviour of wait(2) wrt. SIGCHLD handling. } } } } The wait(2) manpage says: } } } } wait() will fail and return immediately if: } } [ECHILD]The calling process has no existing unwaited-for child } } processes; or no status from the terminated child } } process is available because the calling process has } } asked the system to discard such status by ignoring } } the signal SIGCHLD or setting the flag SA_NOCLDWAIT } } for that signal. } } } } However, ignore is the default handler for SIGCHLD. } } } } So does the } } because the calling process has asked the system } } to discard such status by ignoring the signal SIGCHLD } } mean that explicitly ignoring SIGCHLD is different from ignoring it per default? } >-- End of excerpt from Edgar =?iso-8859-1?B?RnXf?= } } >-- End of excerpt from Brian Buhrow
Re: wait(2) and SIGCHLD
1. Sample program attached. Change SIG_IGN to SIG_DFL to see the difference. 2. macOS seems to behave the same way, as does Linux. 3. I don't see where POSIX defines or allows this, but given 2., I'm surely missing something. 4. The wording in wait(2) could be improved to clarify this is only about SIG_IGN, not SIG_DFL. At least, the NetBSD manpage mentions this at all. 5. Every time I think I knew Unix, I learn otherwise. #include #include #include #include #include #include int stat = 0; int ret; int main(int argc, char * argv[]) { signal(SIGCHLD, SIG_IGN); if (fork()) { if ((ret = wait()) < 0) err(1, "wait"); printf("ret %d, stat %d\n", ret, stat); } else { exit(42); } return 0; }
Re: wait(2) and SIGCHLD
> I'm not sure I've completely understood your question Probably not. Or I don't get what you are trying to say. What I observe is that a process that explicitly ignores SIGCHLD (SIG_IGN), then forks a child which exits, when wait()ing for the child, gets ECHILD (i.e., wait returns -1 and errno is ECHILD).
Re: wait(2) and SIGCHLD
Hello. I'm not sure I've completely understood your question, but I think you're confusing the issue of whether a child posts a SIGCHLD signal when it exits versus whether the current process that's calling wait(2) receives a SIGCHLD when a child exits. The default behavior, as I understand it, is that if a process has children, by default, it will not get signaled if those children terminate. However, if that process then calls wait(2), it will hang until a child terminates, regardless of whether it's configured to receive the SIGCHLD or not. In that instance, I think the man page is wrong, at least if code I have running is to be believed. So, I think there's no difference between the default ignoring of the SIGCHLD signal and explicitly ignoring it. -Brian On Aug 14, 1:51pm, Edgar =?iso-8859-1?B?RnXf?= wrote: } Subject: wait(2) and SIGCHLD } I'm confused regarding the behaviour of wait(2) wrt. SIGCHLD handling. } } The wait(2) manpage says: } } wait() will fail and return immediately if: } [ECHILD]The calling process has no existing unwaited-for child } processes; or no status from the terminated child } process is available because the calling process has } asked the system to discard such status by ignoring } the signal SIGCHLD or setting the flag SA_NOCLDWAIT } for that signal. } } However, ignore is the default handler for SIGCHLD. } } So does the } because the calling process has asked the system } to discard such status by ignoring the signal SIGCHLD } mean that explicitly ignoring SIGCHLD is different from ignoring it per default? >-- End of excerpt from Edgar =?iso-8859-1?B?RnXf?=
Re: wait(2) and SIGCHLD
The second question (that I forgot in the original mail) is whether wait(2) returning ECHILD for whatwever handling of SIGCHLD is covered by POSIX.
Re: wait(2) and SIGCHLD
> So does the > because the calling process has asked the system > to discard such status by ignoring the signal SIGCHLD > mean that explicitly ignoring SIGCHLD is different from ignoring it > per default? I wouldn't say it *means* that, exactly, but I do think that this is a case where SIG_IGN is different from SIG_DFL even when the default action is to do nothing. To put it another way, there are two concepts here, both of which are getting turned into tenses of "ignore" in English. One is a handler of SIG_IGN; the other is SIG_DFL with a default action of "do nothing". The wording in wait(2) is, I believe, talking about only the SIG_IGN kind of ignoring. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTMLmo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Re: wait(2) and SIGCHLD
I agree that this is confusing. While the system definitely differentiates between SIG_DFL and SIG_IGN, the difference would normally not be something I expected to make a difference in something described the way wait(2) is documented. I haven't really bothered going down into the code and find the answer, but I'm curious what other answers pops up for this one. Johnny On 2020-08-14 13:51, Edgar Fuß wrote: I'm confused regarding the behaviour of wait(2) wrt. SIGCHLD handling. The wait(2) manpage says: wait() will fail and return immediately if: [ECHILD]The calling process has no existing unwaited-for child processes; or no status from the terminated child process is available because the calling process has asked the system to discard such status by ignoring the signal SIGCHLD or setting the flag SA_NOCLDWAIT for that signal. However, ignore is the default handler for SIGCHLD. So does the because the calling process has asked the system to discard such status by ignoring the signal SIGCHLD mean that explicitly ignoring SIGCHLD is different from ignoring it per default? -- Johnny Billquist || "I'm on a bus || on a psychedelic trip email: b...@softjar.se || Reading murder books pdp is alive! || tryin' to stay hip" - B. Idol
wait(2) and SIGCHLD
I'm confused regarding the behaviour of wait(2) wrt. SIGCHLD handling. The wait(2) manpage says: wait() will fail and return immediately if: [ECHILD]The calling process has no existing unwaited-for child processes; or no status from the terminated child process is available because the calling process has asked the system to discard such status by ignoring the signal SIGCHLD or setting the flag SA_NOCLDWAIT for that signal. However, ignore is the default handler for SIGCHLD. So does the because the calling process has asked the system to discard such status by ignoring the signal SIGCHLD mean that explicitly ignoring SIGCHLD is different from ignoring it per default?