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