设置进程组可防止子进程启动

问题描述 投票:1回答:1

所以我试图创建一个基本终端,我的问题是:如果我使用以下代码执行大多数“正常”终端命令(例如lscat等),则没有问题。它设置了流程组并且工作完美。但是,当我尝试执行诸如vim .之类的命令时,似乎该过程立即停止。如果我删除对setpgrp()的调用,该命令按预期工作(并使用控制终端的pgid执行)。

这是我的代码:

pid_t normal_cmd(char **argv, int bg) {
    int pid = fork(), status;
    if(pid < 0)
            unix_error("Could not fork child process");
    else if(!pid) { //child (this is the problematic area)
            setpgrp();
            status = execvp(argv[0], argv);
            if(status < 0)
                    unix_error("Could not exec child process");
    }
    else { //parent
            if(!bg) {
                    addjob(jobs, pid, FG);
                    pause(); //waitpid() is in SIGCHLD handler
                    struct job_t *cj = getjobpid(jobs, pid);
                    if(cj && cj->state != ST)
                            deletejob(jobs, pid);
            }
            else
                    addjob(jobs, pid, BG);
    }
    return pid;
}

知道为什么更改进程组会导致vim在这里失败吗?

c terminal process fork exec
1个回答
1
投票

vim将尝试从控制终端读取,并且因为其进程组不是前台进程组,它将收到一个SIGTTIN信号暂停它。 ls和其他“普通”命令不会被暂停,因为它们不从stdin读取(在这种情况下是终端)。

setpgrp()调用具有以调用进程作为其领导者创建新进程组的效果 - 并且新进程组不是终端上的前台进程组,直到您使用tcsetpgrp()或ioctl(TIOCSPGRP)进行此操作)。

您可以阅读更多关于工作控制here的信息。特别是this,它解释了为什么后台程序在尝试从tty读取时会收到SIGTTIN,但如果它尝试写入它则不会收到SIGTTOU。

© www.soinside.com 2019 - 2024. All rights reserved.