根据POSIX规范,如果是背景过程,则tcsetpgrp
可能会导致SIGTTOU
发送到调用过程的组。
但是,我不明白在这种情况下,前景组是否已更改。
另外,如果尽管产生了信号,但我想知道会话会发生什么以及终端是否会接收SIGTTOU
。
tl:dr:
没有前景组不会改变。这是有道理的,因为当该过程更改终端上的设置时,应该发送信号 - 输出操作。如果更改成功,该信号也不会传递到该过程(现在是前景组),因为那时该信号可能会被卡住而没有某人发送Sigcont。
更长的答案:
一个简单的示例:
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
void sig(int signo) {
const char* msg = strsignal(signo); // XXX: Not async-signal-safe.
write(STDOUT_FILENO, msg, strlen(msg));
write(STDOUT_FILENO, "n", 1);
}
int main() {
char cntl_tty[L_ctermid];
ctermid(cntl_tty);
signal(SIGTTOU, sig);
signal(SIGCONT, sig);
int fd = open(cntl_tty, O_RDONLY);
if (fd == -1) {
perror("open");
exit(1);
}
if (tcsetpgrp(fd, getpgrp()) == -1) {
perror("tcsetpgrp");
} else {
puts("foregrounded");
}
return 0;
}
当此代码作为背景过程启动并处理SIGTTOU
时,该循环永远打印了信号。perror
从未被调用,这意味着内核重新启动了系统调用。发送SIGCONT
没关系。前景永远不会成功。然而
当SIGTTOU
的信号处置更改为SIG_IGN
时,立即打印"前置"。