简体   繁体   中英

Why can't the signal handler in the child process be triggered?

My intention is to create a time out of 1 sec for fgets. If no input is received in 1 sec, then the program terminates.

The design I come up with is: the parent registers a signal handler for SIGALRM. Then it forks a child which will trigger SIGALRM and it goes ahead and call fgets. The SIGALRM will trigger the handler which kills the parent process. But when I execute this on a ubuntu 14.04 64-bit, the handler is not triggered and the program just waits for user to input for fgets forever.

Why would this happen and how can I fix this?

#include "csapp.h"                                                              

void handler() {                                                                
  printf("lazy man\n");                                                         
  kill(SIGKILL, getppid());                                                     
  exit(0);                                                                      
}                                                                               

int main() {                                                                    
  char buf[100];                                                                
  signal(SIGALRM, handler);                                                     
  pid_t pid;                                                                    
  if ((pid = fork()) == 0) {                                                    
    alarm(1);                                                                   
  } else {                                                                      
    fgets(buf, 100, stdin);                                                     
    printf("%s", buf);                                                          
  }                                                                             
  return 0;                                                                     
}      

~

If you will take time to read the manual of kill() , you will see that you miss the order of the arguments.

int kill(pid_t pid, int sig);

Fix:

kill(getppid(), SIGKILL); 

Plus, your child terminate his execution before that the signal is raise you must add a sleep() after your call to alarm() to make it wait:

alarm(1);
sleep(2);

Finally, printf() is not safe in a signal handler, list of safe function .

This forking and killing seems wrong. Just set the alarm, register an empty signal handler for SIGALRM, and then check the return value from fgets() - if it fails, check whether errno == EINTR; if it does - it was interrupted by signal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM