2014-10-27 68 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