2014-02-26 82 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將使終端處於翹首狀態。它很難將其恢復到理智的狀態;最好讓程序有機會重新設置自己的終端設置。