Re: Should parent's WIFSIGNALED(siginfo->si_status) be true EVEN IF the SIGNAL was caught by the child?
On Saturday 22 September 2007 16:35:56 Andreas Schwab wrote: > "John Z. Bohach" <[EMAIL PROTECTED]> writes: > > if (WIFEXITED(siginfo->si_status)) > > That does not make any sense. si_status is _not_ a wait status. > > Andreas. Thank you for clearing that up. That explains it. --john - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Should parent's WIFSIGNALED(siginfo->si_status) be true EVEN IF the SIGNAL was caught by the child?
"John Z. Bohach" <[EMAIL PROTECTED]> writes: > if (WIFEXITED(siginfo->si_status)) That does not make any sense. si_status is _not_ a wait status. Andreas. -- Andreas Schwab, SuSE Labs, [EMAIL PROTECTED] SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Should parent's WIFSIGNALED(siginfo->si_status) be true EVEN IF the SIGNAL was caught by the child?
On Saturday 22 September 2007 11:49:09 Michael Kerrisk wrote: > John, > ...snip... > > If the child terminated by calling exit(), regardless of whether it > was done from inside a signal handler, then WIFEXITED() should test > true, but WIFSIGNALED() will not. If you are seeing otherwise, then > show a *short* program that demonstrates the behavior. (But it seems > unlikely that there would be a kernel bug on this point, so do check > your program carefully!) Attached is a (somewhat) short program that demonstates the behavior. I simply compile it with 'make sigtest'. My observed behavior is: $ ./sigtest sigtest started child1 started child2 started selecting... sigCaught: 3366 receieved signal 15 sigtest 3366 exiting sigChld: 3365 receieved signal 17 sigChld: 3365 child 3366 WIFEXITED with childStat 15 sigChld: 3365 child 3366 WIFSIGNALED with si_status 15 select error: Interrupted system call selecting... sigCaught: 3367 receieved signal 15 sigtest 3367 exiting sigChld: 3365 receieved signal 17 sigChld: 3365 child 3367 WIFEXITED with childStat 15 sigChld: 3365 child 3367 WIFSIGNALED with si_status 15 select error: Interrupted system call selecting... sigCaught: 3365 receieved signal 15 sigtest 3365 exiting $ To get this output, I ran, from another shell, the following sequence: $ ps -eaf | grep sigtest zoltan3365 2307 0 13:04 pts/000:00:00 ./sigtest zoltan3366 3365 98 13:04 pts/000:00:06 ./sigtest zoltan3367 3365 98 13:04 pts/000:00:06 ./sigtest $ kill -SIGTERM 3366 $ kill -SIGTERM 3367 $ kill -SIGTERM 3365 That's it. What I find odd is that the wait_pid() status and the si_status are the same for both a WIFEXITED and a WIFSIGNALED, which should be impossible, if I read the documentation right. Thanks for your responses, John #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SER_PORT_ID 1234 /* The server's port */ static int child;/* child = 0, parent != 0 */ static void child1(void); static void child2(void); static void sigChld(int signum, siginfo_t * siginfo, void * ucontext); static void sigCaught(int signum, siginfo_t * siginfo, void * ucontext); static void setupEnv(void); static void serverLoop(void); static void processConnect(int csfd); static void sigtestExit(); /** * main: * @argc: The count of command line data * @argv: The array of command line strings * * The entry point of the executable. */ int main(int argc, char * argv[]) { setupEnv(); /* * spawn two child processes so they (the children) can be sent SIGNAL's * and the behaviour can be observed... */ if ((child = fork()) < 0)/* fork error */ { perror("Child1 could not be created"); exit(1); } else if (child == 0) /* In child */ { child1();/* never returns... */ } if ((child = fork()) < 0)/* fork error */ { perror("Monitor child could not be created"); exit(1); } else if (child == 0) /* In child */ { child2();/* never returns... */ } serverLoop();/* Never returns */ return 0; } /** * child1: * * This is the first child. */ static void child1(void) { printf("child1 started\n"); for ( ; ; ); } /** * child2: * * This is the second child. */ static void child2(void) { printf("child2 started\n"); for ( ; ; ); } /** * sigChild: * @signum: The signal that got us here. * @siginfo: Additional data associated with the signal. * @ucontext: Pointer to ucontext_t struct. Unused here. * * Signal handler for catching SIGCHLD. Is re-entrant... */ static void sigChld(int signum, siginfo_t * siginfo, void * ucontext) { int childStat; printf("sigChld: %d receieved signal %d\n", getpid(), signum); if (signum != SIGCHLD) /* technically can't happen here... */ return; /* but ignore it if it does */ waitpid(siginfo->si_pid, , 0); /* orderly child shutdown... */ /* * These next 4 if blocks are where it gets interesting...this I believe * demonstrates the inconsistency. */ if (WIFEXITED(childStat)) printf("sigChld: %d child %d WIFEXITED with childStat %d\n", getpid(), siginfo->si_pid, WEXITSTATUS(childStat)); if (WIFEXITED(siginfo->si_status)) printf("sigChld: %d child %d WIFEXITED with si_status %d\n", getpid(), siginfo->si_pid, WEXITSTATUS(siginfo->si_status)); if (WIFSIGNALED(childStat)) { printf("sigChld: %d child %d WIFSIGNALED with childStat %d\n", getpid(), siginfo->si_pid, WTERMSIG(childStat)); } if
Re: Should parent's WIFSIGNALED(siginfo->si_status) be true EVEN IF the SIGNAL was caught by the child?
On Sat, 2007-09-22 at 11:22 -0700, John Z. Bohach wrote: > Hello, > > It is unclear from the various documentions in the kernel and glibc what > the proper behaviour should be for the case when a child process > catches a SIGNAL (say for instance, SIGTERM), and then calls exit() > from within its caught SIGNAL handler. > > Since the exit() will cause a SIGCHLD to the parent, and the parent > (let's say) has a SIGCHLD sigaction (SA_SIGINFO sa_flags set), should > the parent's WIFSIGNALED(siginfo->si_status) be true? > > To recap, the WIFSIGNALED section of the waitpid() manpage says: > > WIFSIGNALED(status) > returns true if the child process was terminated by a signal. > > So the dilemna: the child caught the signal, so it wasn't terminated by > a signal, but rather its signal handler (let's say) called exit. POSIX says WIFSIGNALED(stat_val) Evaluates to a non-zero value if status was returned for a child process that terminated due to the receipt of a signal that was not caught (see ). So there's no dilemma at all and Linux is non-conformant. -- Nicholas Miell <[EMAIL PROTECTED]> - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Should parent's WIFSIGNALED(siginfo->si_status) be true EVEN IF the SIGNAL was caught by the child?
John, > It is unclear from the various documentions in the kernel and glibc what > the proper behaviour should be for the case when a child process > catches a SIGNAL (say for instance, SIGTERM), and then calls exit() > from within its caught SIGNAL handler. > > Since the exit() will cause a SIGCHLD to the parent, and the parent > (let's say) has a SIGCHLD sigaction (SA_SIGINFO sa_flags set), should > the parent's WIFSIGNALED(siginfo->si_status) be true? > > To recap, the WIFSIGNALED section of the waitpid() manpage says: > > WIFSIGNALED(status) >returns true if the child process was terminated by a signal. > > So the dilemna: the child caught the signal, so it wasn't terminated by > a signal, but rather its signal handler (let's say) called exit. > > Furthermore: > > WTERMSIG(status) >returns the number of the signal that caused the child process >to terminate. This macro should only be employed if WIFSIGNALED >returned true. > > Observered behaviour with 2.6.20.6 is that is WIFSIGNALED(status) > returns true (possibly incorrect), and furthermore, WTERMSIG(status) > returns the exit(VALUE) VALUE from the child's exit() call, and not the > SIGNAL (let's say SIGTERM that the child caught). This may be correct, > since the siginfo_t * si_status member is: > > int si_status; /* Exit value or signal */ > > but there's no clarity on which: exit value or signal. Since the child > exited, I'm likely to assume exit status, which is current observed > behaviour, but then, WIFSIGNALED(status) should be FALSE, which its not > (observed with 2.6.20.6). > > So could someone clarify the kernel's intent? > > I can provide a short C program to illustrate above behaviour, if > needed. It also could be that I'm just misinterpreting the intent, > which is why I'm not calling this a bug, despite a possible > inconsistency in behaviour. If the child terminated by calling exit(), regardless of whether it was done from inside a signal handler, then WIFEXITED() should test true, but WIFSIGNALED() will not. If you are seeing otherwise, then show a *short* program that demonstrates the behavior. (But it seems unlikely that there would be a kernel bug on this point, so do check your program carefully!) Cheers, Michael - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Should parent's WIFSIGNALED(siginfo->si_status) be true EVEN IF the SIGNAL was caught by the child?
Hello, It is unclear from the various documentions in the kernel and glibc what the proper behaviour should be for the case when a child process catches a SIGNAL (say for instance, SIGTERM), and then calls exit() from within its caught SIGNAL handler. Since the exit() will cause a SIGCHLD to the parent, and the parent (let's say) has a SIGCHLD sigaction (SA_SIGINFO sa_flags set), should the parent's WIFSIGNALED(siginfo->si_status) be true? To recap, the WIFSIGNALED section of the waitpid() manpage says: WIFSIGNALED(status) returns true if the child process was terminated by a signal. So the dilemna: the child caught the signal, so it wasn't terminated by a signal, but rather its signal handler (let's say) called exit. Furthermore: WTERMSIG(status) returns the number of the signal that caused the child process to terminate. This macro should only be employed if WIFSIGNALED returned true. Observered behaviour with 2.6.20.6 is that is WIFSIGNALED(status) returns true (possibly incorrect), and furthermore, WTERMSIG(status) returns the exit(VALUE) VALUE from the child's exit() call, and not the SIGNAL (let's say SIGTERM that the child caught). This may be correct, since the siginfo_t * si_status member is: int si_status; /* Exit value or signal */ but there's no clarity on which: exit value or signal. Since the child exited, I'm likely to assume exit status, which is current observed behaviour, but then, WIFSIGNALED(status) should be FALSE, which its not (observed with 2.6.20.6). So could someone clarify the kernel's intent? I can provide a short C program to illustrate above behaviour, if needed. It also could be that I'm just misinterpreting the intent, which is why I'm not calling this a bug, despite a possible inconsistency in behaviour. Thanks, John - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Should parent's WIFSIGNALED(siginfo-si_status) be true EVEN IF the SIGNAL was caught by the child?
Hello, It is unclear from the various documentions in the kernel and glibc what the proper behaviour should be for the case when a child process catches a SIGNAL (say for instance, SIGTERM), and then calls exit() from within its caught SIGNAL handler. Since the exit() will cause a SIGCHLD to the parent, and the parent (let's say) has a SIGCHLD sigaction (SA_SIGINFO sa_flags set), should the parent's WIFSIGNALED(siginfo-si_status) be true? To recap, the WIFSIGNALED section of the waitpid() manpage says: WIFSIGNALED(status) returns true if the child process was terminated by a signal. So the dilemna: the child caught the signal, so it wasn't terminated by a signal, but rather its signal handler (let's say) called exit. Furthermore: WTERMSIG(status) returns the number of the signal that caused the child process to terminate. This macro should only be employed if WIFSIGNALED returned true. Observered behaviour with 2.6.20.6 is that is WIFSIGNALED(status) returns true (possibly incorrect), and furthermore, WTERMSIG(status) returns the exit(VALUE) VALUE from the child's exit() call, and not the SIGNAL (let's say SIGTERM that the child caught). This may be correct, since the siginfo_t * si_status member is: int si_status; /* Exit value or signal */ but there's no clarity on which: exit value or signal. Since the child exited, I'm likely to assume exit status, which is current observed behaviour, but then, WIFSIGNALED(status) should be FALSE, which its not (observed with 2.6.20.6). So could someone clarify the kernel's intent? I can provide a short C program to illustrate above behaviour, if needed. It also could be that I'm just misinterpreting the intent, which is why I'm not calling this a bug, despite a possible inconsistency in behaviour. Thanks, John - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Should parent's WIFSIGNALED(siginfo-si_status) be true EVEN IF the SIGNAL was caught by the child?
John, It is unclear from the various documentions in the kernel and glibc what the proper behaviour should be for the case when a child process catches a SIGNAL (say for instance, SIGTERM), and then calls exit() from within its caught SIGNAL handler. Since the exit() will cause a SIGCHLD to the parent, and the parent (let's say) has a SIGCHLD sigaction (SA_SIGINFO sa_flags set), should the parent's WIFSIGNALED(siginfo-si_status) be true? To recap, the WIFSIGNALED section of the waitpid() manpage says: WIFSIGNALED(status) returns true if the child process was terminated by a signal. So the dilemna: the child caught the signal, so it wasn't terminated by a signal, but rather its signal handler (let's say) called exit. Furthermore: WTERMSIG(status) returns the number of the signal that caused the child process to terminate. This macro should only be employed if WIFSIGNALED returned true. Observered behaviour with 2.6.20.6 is that is WIFSIGNALED(status) returns true (possibly incorrect), and furthermore, WTERMSIG(status) returns the exit(VALUE) VALUE from the child's exit() call, and not the SIGNAL (let's say SIGTERM that the child caught). This may be correct, since the siginfo_t * si_status member is: int si_status; /* Exit value or signal */ but there's no clarity on which: exit value or signal. Since the child exited, I'm likely to assume exit status, which is current observed behaviour, but then, WIFSIGNALED(status) should be FALSE, which its not (observed with 2.6.20.6). So could someone clarify the kernel's intent? I can provide a short C program to illustrate above behaviour, if needed. It also could be that I'm just misinterpreting the intent, which is why I'm not calling this a bug, despite a possible inconsistency in behaviour. If the child terminated by calling exit(), regardless of whether it was done from inside a signal handler, then WIFEXITED() should test true, but WIFSIGNALED() will not. If you are seeing otherwise, then show a *short* program that demonstrates the behavior. (But it seems unlikely that there would be a kernel bug on this point, so do check your program carefully!) Cheers, Michael - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Should parent's WIFSIGNALED(siginfo-si_status) be true EVEN IF the SIGNAL was caught by the child?
On Sat, 2007-09-22 at 11:22 -0700, John Z. Bohach wrote: Hello, It is unclear from the various documentions in the kernel and glibc what the proper behaviour should be for the case when a child process catches a SIGNAL (say for instance, SIGTERM), and then calls exit() from within its caught SIGNAL handler. Since the exit() will cause a SIGCHLD to the parent, and the parent (let's say) has a SIGCHLD sigaction (SA_SIGINFO sa_flags set), should the parent's WIFSIGNALED(siginfo-si_status) be true? To recap, the WIFSIGNALED section of the waitpid() manpage says: WIFSIGNALED(status) returns true if the child process was terminated by a signal. So the dilemna: the child caught the signal, so it wasn't terminated by a signal, but rather its signal handler (let's say) called exit. POSIX says WIFSIGNALED(stat_val) Evaluates to a non-zero value if status was returned for a child process that terminated due to the receipt of a signal that was not caught (see signal.h). So there's no dilemma at all and Linux is non-conformant. -- Nicholas Miell [EMAIL PROTECTED] - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Should parent's WIFSIGNALED(siginfo-si_status) be true EVEN IF the SIGNAL was caught by the child?
On Saturday 22 September 2007 11:49:09 Michael Kerrisk wrote: John, ...snip... If the child terminated by calling exit(), regardless of whether it was done from inside a signal handler, then WIFEXITED() should test true, but WIFSIGNALED() will not. If you are seeing otherwise, then show a *short* program that demonstrates the behavior. (But it seems unlikely that there would be a kernel bug on this point, so do check your program carefully!) Attached is a (somewhat) short program that demonstates the behavior. I simply compile it with 'make sigtest'. My observed behavior is: $ ./sigtest sigtest started child1 started child2 started selecting... sigCaught: 3366 receieved signal 15 sigtest 3366 exiting sigChld: 3365 receieved signal 17 sigChld: 3365 child 3366 WIFEXITED with childStat 15 sigChld: 3365 child 3366 WIFSIGNALED with si_status 15 select error: Interrupted system call selecting... sigCaught: 3367 receieved signal 15 sigtest 3367 exiting sigChld: 3365 receieved signal 17 sigChld: 3365 child 3367 WIFEXITED with childStat 15 sigChld: 3365 child 3367 WIFSIGNALED with si_status 15 select error: Interrupted system call selecting... sigCaught: 3365 receieved signal 15 sigtest 3365 exiting $ To get this output, I ran, from another shell, the following sequence: $ ps -eaf | grep sigtest zoltan3365 2307 0 13:04 pts/000:00:00 ./sigtest zoltan3366 3365 98 13:04 pts/000:00:06 ./sigtest zoltan3367 3365 98 13:04 pts/000:00:06 ./sigtest $ kill -SIGTERM 3366 $ kill -SIGTERM 3367 $ kill -SIGTERM 3365 That's it. What I find odd is that the wait_pid() status and the si_status are the same for both a WIFEXITED and a WIFSIGNALED, which should be impossible, if I read the documentation right. Thanks for your responses, John #include stdio.h #include stdlib.h #include string.h #include unistd.h #include limits.h #include dirent.h #include errno.h #include time.h #include pwd.h #include signal.h #include syslog.h #include netinet/in.h #include sys/types.h #include sys/inotify.h #include sys/socket.h #include sys/select.h #include sys/wait.h #define SER_PORT_ID 1234 /* The server's port */ static int child;/* child = 0, parent != 0 */ static void child1(void); static void child2(void); static void sigChld(int signum, siginfo_t * siginfo, void * ucontext); static void sigCaught(int signum, siginfo_t * siginfo, void * ucontext); static void setupEnv(void); static void serverLoop(void); static void processConnect(int csfd); static void sigtestExit(); /** * main: * @argc: The count of command line data * @argv: The array of command line strings * * The entry point of the executable. */ int main(int argc, char * argv[]) { setupEnv(); /* * spawn two child processes so they (the children) can be sent SIGNAL's * and the behaviour can be observed... */ if ((child = fork()) 0)/* fork error */ { perror(Child1 could not be created); exit(1); } else if (child == 0) /* In child */ { child1();/* never returns... */ } if ((child = fork()) 0)/* fork error */ { perror(Monitor child could not be created); exit(1); } else if (child == 0) /* In child */ { child2();/* never returns... */ } serverLoop();/* Never returns */ return 0; } /** * child1: * * This is the first child. */ static void child1(void) { printf(child1 started\n); for ( ; ; ); } /** * child2: * * This is the second child. */ static void child2(void) { printf(child2 started\n); for ( ; ; ); } /** * sigChild: * @signum: The signal that got us here. * @siginfo: Additional data associated with the signal. * @ucontext: Pointer to ucontext_t struct. Unused here. * * Signal handler for catching SIGCHLD. Is re-entrant... */ static void sigChld(int signum, siginfo_t * siginfo, void * ucontext) { int childStat; printf(sigChld: %d receieved signal %d\n, getpid(), signum); if (signum != SIGCHLD) /* technically can't happen here... */ return; /* but ignore it if it does */ waitpid(siginfo-si_pid, childStat, 0); /* orderly child shutdown... */ /* * These next 4 if blocks are where it gets interesting...this I believe * demonstrates the inconsistency. */ if (WIFEXITED(childStat)) printf(sigChld: %d child %d WIFEXITED with childStat %d\n, getpid(), siginfo-si_pid, WEXITSTATUS(childStat)); if (WIFEXITED(siginfo-si_status)) printf(sigChld: %d child %d WIFEXITED with si_status %d\n, getpid(), siginfo-si_pid, WEXITSTATUS(siginfo-si_status)); if (WIFSIGNALED(childStat)) { printf(sigChld: %d child %d
Re: Should parent's WIFSIGNALED(siginfo-si_status) be true EVEN IF the SIGNAL was caught by the child?
John Z. Bohach [EMAIL PROTECTED] writes: if (WIFEXITED(siginfo-si_status)) That does not make any sense. si_status is _not_ a wait status. Andreas. -- Andreas Schwab, SuSE Labs, [EMAIL PROTECTED] SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 And now for something completely different. - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Should parent's WIFSIGNALED(siginfo-si_status) be true EVEN IF the SIGNAL was caught by the child?
On Saturday 22 September 2007 16:35:56 Andreas Schwab wrote: John Z. Bohach [EMAIL PROTECTED] writes: if (WIFEXITED(siginfo-si_status)) That does not make any sense. si_status is _not_ a wait status. Andreas. Thank you for clearing that up. That explains it. --john - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/