フォアグラウンドプロセスグループに子プロセスを追加することはできません。

フォアグラウンドプロセスグループに子プロセスを追加することはできません。

フォアグラウンドプロセスグループに子プロセスを追加しようとしています。分岐後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()そのグループから呼び出すことです。

おすすめ記事