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

六眼飞鱼酱① 提交于 2019-12-12 05:42:01

问题


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;                                                                     
}      

~


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/44350429/why-cant-the-signal-handler-in-the-child-process-be-triggered

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!