2014-02-26 41 views
0

我有一个主要从命令行参数运行程序。命令行程序分叉并在子进程中运行。当SIGINT发送时,我想抓住它并要求用户确认他/她想要退出。如果是的话,父母和孩子都结束,否则孩子会继续跑步。 我的问题是,我不能让孩子开始跑回来,当用户说不。 我试过SIGSTOP & SIGCONT,但这些实际上只是导致进程停止。如何捕获SIGINT并在子进程中忽略它?

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <ctype.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <errno.h> 

extern char **environ; 
void sigint_handler(int sig); 
void sigint_chldhandler(int sig); 

int main(int argc, char** argv) 
{ 
    int pid; 
    signal(SIGINT,sigint_handler); 


    if((pid=fork())==0) 
    { 
      printf("%d\n",pid); 

      execve(argv[1],argv,environ); 
    } 


    int status; 
    waitpid(pid,&status,0); 
} 
void sigint_handler(int sig) 
{ 
    printf("Do you want to quit?Yes/No:\n"); 
    char buf[4]; 
    fgets(buf, sizeof(char)*4, stdin); 

    printf("child pid:%d\n",getpid()); 
    printf("parent pid:%d\n",getppid()); 

    if(strcmp(buf,"Yes")==0) 
    { 
      kill(-getpid(),SIGKILL); 
      printf("Exiting!\n"); 
      exit(0); 
    } 

} 
+1

http://stackoverflow.com/questions/6803395/child-process-receives-parents-sigint - 是吗? – someuser

+0

你也可以在子进程中使用'signal(SIGINT,SIG_IGN);',或者为它写另一个SIGINT处理程序。 – someuser

+0

如果我阻止sigint,那么当用户按下ctrl C时,infite子进程永远不会停止。我想发送cntl C sig并要求用户确认他是否真的要退出,如果用户说没有,那么子进程继续 – user3213348

回答

0

SIGINT来到父进程和子进程(到进程组)。
父进程调用您的处理程序。
子进程默认处理此信号。
您可以使用此,例如:

#include <unistd.h> 
#include <signal.h> 
#include <stdio.h> 
int main() 
{ 
    pid_t pid; 
    char c; 
    switch(pid = fork()) 
    { 
     case -1: 
      printf("!!!"); 
      return -1; 
     break; 
     case 0: 
      printf("child started\n"); 
      while(1) { }; 
     break; 
     default: 
      while(1) 
      { 
       c = getchar(); 
       if(c == 'q') 
       {  
         //your conditions 
         kill(pid, SIGKILL); 
         return 0; 
       } 
      } 
     break; 
    } 
    return 0; 
} 
0

除非你装备孩子的信号处理,它将被中断时发出的信号,无论在父会发生什么终止。因此,你需要更复杂。我认为你需要一些东西:

  1. 父进程设置它的SIGINT信号处理程序。
  2. 父叉。
  3. 子进程将其SIGINT处理设置为SIG_IGN。
  4. 子执行指定的命令。
  5. 家长等待SIGINT到达,可能在运行时waitpid()
  6. 当它到达时,它向小孩发送SIGSTOP。
  7. 它提出问题并得到回应。
  8. 如果响应继续,则它将SIGCONT发送给子节点并返回到其等待模式。
  9. 如果响应停止,那么它首先发送SIGCONT,然后发送SIGTERM(或SIGINT以外的其他信号)给该子节点以杀死它。 (使用SIGKILL是不明智的;如果孩子没有认真对待死亡威胁,那么应该让孩子有机会退出SIGTERM或SIGHUP。)
  10. 当父母有确定孩子已经退出,可以自行退出。

请注意,如果子进程正在运行类似vim这样的显着更改终端设置的操作,那么发送SIGKILL将使终端处于翘首状态。它很难将其恢复到理智的状态;最好让程序有机会重新设置自己的终端设置。