无法在前台进程组中添加子进程

无法在前台进程组中添加子进程

我正在尝试在前台进程组中添加一个子进程。分叉后,我调用execve()生成一个新进程(在本例中为 unix echo 程序)。在调用之前,execve()我正在使用子进程的 pid 创建一个新的进程组。因此,孩子正在成为该流程组的流程领导者。之后我调用tcsetpgrp()将进程组添加到前台进程组中。

当我运行该程序时,它挂在tcsetpgrp()调用中。execve()从不执行。如果我删除tcsetpgrp()调用,则execve()执行成功。

无法理解为什么会发生这种情况。以下是我写的代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void pr_ids(char *name){
    pid_t pid, ppid, pgid, tpgid;

    pid = getpid();
    ppid = getppid();
    pgid = getpgrp(); 
    tpgid = tcgetpgrp(STDIN_FILENO);

    printf("%s: pid = %d ppid = %d"
           " pgid = %d tpgid = %d\n", name, pid, ppid, pgid, tpgid);
}

int main(int argc, char *argv[]){
    pid_t pid;
    int st;
    char *args[] = {"/bin/echo", "hello", NULL};

    pr_ids("parent"); 

    if((pid = fork()) == 0){
        setpgid(0, 0);  // creates its own process group and becomes group leader
        pr_ids("child");
        pid_t cpgrp = getpgrp();
        tcsetpgrp(STDIN_FILENO, cpgrp);     // add the process group to foreground
        pr_ids("child");
        execve(args[0], args, NULL); 
    }
    else if(pid > 0){
        waitpid(pid, &st, 0); 
    }

    exit(0);
}

答案1

tcsetpgrp()不将进程添加到进程组,而是设置终端的前台进程组。如果tcsetpgrp()从后台进程组调用,则调用进程(及其进程组中的所有进程)SIGTTOU将从内核获得一个信号,除非被捕获,否则将停止它们。

这正是您的示例中发生的情况:您正在创建另一个进程组,然后tcsetpgrp()从其中进行调用。

相关内容