当调用者属于后台进程时,tcsetpgrp()是否成功?

时间:2017-12-01 17:51:56

标签: c signals posix

根据POSIX specificationtcsetpgrp可以导致SIGTTOU被发送到调用进程的组(如果它是后台进程)。

但是,如果在这种情况下前景组被更改,我无法理解。

此外,如果尽管信号生成实际上改变了前景组,我想知道如果新的前景组是将要接收SIGTTOU的那个,会话和终端会发生什么。

1 个答案:

答案 0 :(得分:1)

<强> 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”。