2011-03-04 36 views
1
#include <stdio.h> 
#include <string.h> 
#include <strings.h> 
#include <limits.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <pwd.h> 
#include <dirent.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <signal.h> 


void sig_handler(int signal); 

int pid, forkFlag = 0; 

int main(int argc, char **argv, char **envp) 
{ 
    sigset(SIGINT, sig_handler); //handle ctrl + c 
    sigignore(SIGTSTP); 
    sigignore(SIGSTOP); 

int ex, rv, status; 
     forkFlag = 1; //fork is being called 

     pid = fork(); 

     if(pid == -1){ 

      perror("fork"); 
      exit(2); 
     } 
     else if (pid == 0){ //if child process 

      ex = access(argv[0], X_OK); //check if file is executable 

      if(ex){ 

       perror("access"); 
       exit(1); 
      } 
      else{ 
       rv = execve(argv[0], argv, envp); //run program in child process 

       if(rv == -1){ 

        perror("execve"); 
        exit(1); 
       } 
      } 
      exit(0); //end child process 
     } 
     else{ 
      rv = waitpid(pid, &status, 0); //wait for child 

      if(rv == -1){ 

       perror("waitpid"); 
      } 

      if(WEXITSTATUS(status)){ //check status of child if it did ot return 0 

       printf("The return status of the child was %d\n", WEXITSTATUS(status)); 
      } 
     } 
     forkFlag=0; 
} 

void sig_handler(int signal) 
{ 
    if(signal == SIGINT && (pid && forkFlag)){ 

     kill(pid,signal); //send kill to child 
    } 
} 

我想讓我的程序忽略ctrl + C,除非有一個子進程在運行,那麼它會將SIGINT發送到子進程。但是,當子進程正在運行時,按ctrl + c時,waitpid()返回-1,並顯示錯誤「Interrupted System Call」。這使得子進程停止運行,但是如果我使用ps,那麼子進程仍然存在,但現在標記爲「已停用」。我從printf語句知道kill是函數sig_handler的函數,而pid和forkFlag是它們的正確值。 waitpid()讓我的程序忽略殺手?我該如何解決?我知道這個代碼幾乎沒有,但它是我的代碼的一小部分(唯一涉及叉的部分)waitpid()不允許將SIGINT發送給子進程?

感謝您的任何幫助。

回答

2

問題是子進程獲取與SIGINT相同的重寫處理程序。您可能希望在fork之後重置子進程中的信號處理程序,或者您可能希望在派生子程序之後將信號處理程序安裝在父項中,因此它不會繼承overriden處理程序。

+1

這是真的嗎?我認爲'execve()'重置了子進程中未忽略信號的信號處置。 – 2013-12-05 04:32:28