【问题标题】:Detecting SIGTTIN when a child background process runs "cat"当子后台进程运行“cat”时检测 SIGTTIN
【发布时间】:2014-10-27 04:59:25
【问题描述】:

我有以下程序,我在其中设置父进程组和子进程组,并将终端控制权交给父进程。然后,我在“背景”孩子中运行“猫”,它应该生成 SIGTTIN。但是,不打印 sighandler 中的 printf 行。在这种情况下如何正确检测 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;
}

【问题讨论】:

    标签: c signals


    【解决方案1】:

    玛莉丝卡,

    对于父进程

    正如标题为“Catch Ctrl-C in C”的 Stack Overflow 帖子中所述:

    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()),然后信号会自动传播给孩子。 是我们需要更改信号处理程序的原因。即使孩子当前处于“活动状态”,父母仍然会在孩子之前收到信号。

    如果您有任何问题,请告诉我!

    【讨论】:

    • 在我上面的程序中尝试从后台进程读取 STDIN 的子进程中检测 SIGTTIN 怎么样?即使使用 sigaction 我似乎也无法检测到它..
    • 嘿 Mariska,更新了!如果您有任何问题,请告诉我!
    猜你喜欢
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    相关资源
    最近更新 更多