我有以下程序,我设置父进程组和子进程组,并将终端控件提供给父进程。然后,我在“background”子项中运行“cat”,它应该生成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;
}
答案 0 :(得分:3)
玛莉丝卡哈,
对于父流程
正如Stack Overflow帖子中所解释的那样," 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 */
}
儿童流程
在处理子进程的信号处理程序时,您应该知道几点:
正如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()
),然后然后信号自动传播给儿童。 这个是我们需要更改信号处理程序的原因。即使孩子目前处于活动状态,父母仍会在孩子出现之前收到信号。
如果您有任何疑问,请与我们联系!