2014-12-19 52 views
1

我使用tcsetpgrp()函数,我在gcc编译器中运行此代码。我想将STDOUT_FILENO更改为由子进程创建的新组。为什么子进程终止?请解释我?

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int 
main (void) 
{ 
    printf("Parent pgid=%d\n", getpgrp()); 
    printf("STDOUT(parent)=%d\n", tcgetpgrp(STDOUT_FILENO)); 
    pid_t pid; 
    if(0 == (pid = fork())) 
    { 
     setpgid(0, 0);  
     printf("child pgid=%d\n", getpgrp()); 
     if(0 != tcsetpgrp(STDOUT_FILENO, 0)) 
     perror("Error"); 
     printf("After changing %d\n", tcgetpgrp(STDOUT_FILENO)); 
     exit(0); 
    } 
    wait(0); 
    return 0; 
} 
在当tcsetpgrp()函数达到终止子进程和退出状态并不父母报告孩子的过程

+0

btw你想达到什么:)? – 2014-12-19 09:39:26

+1

我认为你忽略了这个“如果setpgid()用于将进程 从一个进程组移动到另一个进程组(如创建管道时由某些shell执行的操作),则两个进程组必须是同一会话的一部分(请参阅setsid(2)和凭据(7))。“ – 2014-12-19 09:41:37

+0

是的,你可能必须调用'setsid' – Zaffy 2014-12-19 09:43:17

回答

2

当子进程调用tcsetpgrp时,它收到SIGTTOU信号,导致信号停止。当子进程停止时,父进程阻止对wait的调用,等待子进程终止。

简单的解决办法是忽略孩子SIGTTOU信号,只需调用fork后:

signal(SIGTTOU, SIG_IGN) 

没有您的代码中的另一个问题 - 你试图改变终端的进程组为0,这没有任何意义。你可能想说:

tcsetpgrp(STDOUT_FILENO, getpgrp())