2014-10-27 69 views
1

我有以下程序,我設置父進程組和子進程組,並將終端控制權交給父進程組。然後,我在「背景」孩子中運行「貓」,該孩子應該生成SIGTTIN。但是,sighandler中的printf行不會被打印。任何想法如何在這種情況下正確檢測SIGTTIN?當孩子後臺進程運行「貓」時檢測SIGTTIN

void sighandler(int signo){ 
    printf("SIGTTIN detected\n"); 
} 

int main() { 


    int status; 
    pid_t pid; 
    pid = fork(); 

    setpgid(0,0); 

    tcsetpgrp (STDIN_FILENO, 0); 

    signal(SIGTTIN, sighandler); 


    if (pid == 0) 
    { 
     setpgid(0,0); 
     execl ("cat", NULL); 
     _exit (EXIT_FAILURE); 
    } 
    else{ 
    int status; 
    setpgid(pid,pid); 
    waitpid(-1, &status, 0); 
    } 
    return status; 
} 

回答

3

瑪莉絲卡哈,

對於父進程

正如標題爲堆棧溢出後解釋說, 「Catch Ctrl-C in C」:

The behavior of signal() varies across UNIX versions, and has also 
varied historically across different versions of Linux. Avoid its use: 
use sigaction(2) instead. 

使用Linux程序員Manual描述,你應該使用sigaction()

The sigaction() system call is used to change the action taken by a 
process on receipt of a specific signal. 

試試這個:

#include<stdio.h> 
#include <signal.h> 


static void handler(int signum) 
{ 
    /* Take appropriate actions for signal delivery */ 
    printf("SIGTTIN detected\n"); 
} 


int main() 
{ 
    struct sigaction sa; 


    sa.sa_handler = handler; 
    sigemptyset(&sa.sa_mask); 
    sa.sa_flags = SA_RESTART; /* Restart functions if 
           interrupted by handler */ 
    if (sigaction(SIGINT, &sa, NULL) == -1) 
     /* Handle error */; 


    /* Further code */ 
} 

子進程

有幾個點與信號處理程序處理的子進程時,你應該知道:

  1. 分叉的孩子繼承父母的信號處理程序
  2. 由於上述原因,需要爲父級實現某種信號處理程序,然後在執行子級之前和之後更改信號處理程序。
  3. 使用Linux程序員Manual解釋說:

    All process attributes are preserved during an execve(), except the following: 
          a. The set of pending signals is cleared (sigpending(2)). 
          b. The dispositions of any signals that are being caught are 
           reset to being ignored. 
          c. Any alternate signal stack is not preserved (sigaltstack(2)). 
    

    因此,EXEC()函數不保留信號處理程序。

從上面的,我想告訴你,按Ctrl-C將信號發送到父進程(除非您使用exec()),並然後的信號會自動傳播給孩子。 這是是我們需要更改信號處理程序的原因。即使孩子目前「活躍」,父母仍然會在孩子面前接收到信號。

如果您有任何問題,請讓我知道!

+0

如何在一個子進程中檢測SIGTTIN,試圖從上面的程序中讀取後臺進程中的STDIN?我似乎無法檢測到它甚至使用sigaction .. – Mariska 2014-10-27 11:17:33

+0

嘿Mariska,更新!請讓我知道,如果你有任何問題! – 2014-10-27 16:33:15