当调用者属于后台进程时,tcsetpgrp() 是否成功?
Does tcsetpgrp() succeds when the caller belong to a background process?
根据POSIX specification,如果是后台进程,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
没有关系。前景永远不会成功。但是,当通过 shell 将代码置于前台时,"foregrounded" 会按预期打印。
当 SIGTTOU
的信号配置更改为 SIG_IGN
时,立即打印 "foregrounded"。
根据POSIX specification,如果是后台进程,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
没有关系。前景永远不会成功。但是,当通过 shell 将代码置于前台时,"foregrounded" 会按预期打印。
当 SIGTTOU
的信号配置更改为 SIG_IGN
时,立即打印 "foregrounded"。