Project

General

Profile

Bug #3329

Updated by tuxillo over 1 year ago

The macro @WIFSIGNALED(status)@ WIFSIGNALED(status) gives true even when the child process is 
 continued by a signal SIGCONT. I think it should be true ONLY IF the 
 child is terminated by a signal, as described in wait(2) man page. 

 On DragonFly 6.2, an example C program (see the end of this post) gives: 

 <pre> 
 0x117f: stopped 
 0x0013: signaled: 19 
 0x0013: continued 
 0x0000: exited: 0 
 </pre> 

 The two lines with status=0x0013 shows that both @WIFSIGNALED(status)@ WIFSIGNALED(status) and 
 @WIFCONTINUED(status)@ WIFCONTINUED(status) are true for this status. 

 On FreeBSD it gives: 

 <pre> 
 0x117f: stopped 
 0x0013: continued 
 0x0000: exited: 0 
 </pre> 

 The line 'signaled' is not output also on Linux and macOS. 

 On FreeBSD the macro is defined (in sys/wait.h) as follows: 

 <pre> 
 <code class="C"> 
 #define WIFSIGNALED(x)    (_WSTATUS(x) != _WSTOPPED && _WSTATUS(x) != 0 && (x) != 0x13) 
 </code> 
 </pre> 

 I think DragonFly should use the same definition. 

 Jun 


 /*==== an example C program ======*/ 

 <pre> 
 <code class="C"> 
 #include <stdio.h> 
 #include <unistd.h> 
 #include <sys/types.h> 
 #include <sys/wait.h> 
 #include <signal.h> 

 pid_t child; 
 int done = 0; 

 void handler(int sig) 
 { 
 int status; 
 while(waitpid(child, &status, WNOHANG|WUNTRACED|WCONTINUED) == child) { 
 if (WIFEXITED(status)) { 
 printf("0x%04x: exited: %d\n", status, WEXITSTATUS(status)); 
 done = 1; 
 } 
 if (WIFSIGNALED(status)) 
 printf("0x%04x: signaled: %d\n", status, WTERMSIG(status)); 
 if (WIFCONTINUED(status)) 
 printf("0x%04x: continued\n", status); 
 if (WIFSTOPPED(status)) 
 printf("0x%04x: stopped\n", status); 
 } 
 } 

 int main(void) 
 { 
 signal(SIGCHLD, handler); 

 if ((child = fork()) > 0) { 
 kill(child, SIGSTOP); 
 sleep(1); 
 kill(child, SIGCONT); 
 /* explicitly call handler() since we will not receive SIGCHLD */ 
 handler(SIGCHLD); 
 while(!done) { 
 sleep(1);     /* wait for child to exit */ 
 } 
 } 
 else { /* child */ 
 sleep(1); 
 } 
 return 0; 
 } 
 </code> 
 </pre>

Back