子进程在父进程退出后无法从终端读取

时间:2015-10-30 12:07:16

标签: c linux bash process fork

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

int main() {
    int pid = -1; 
    char buf[10] = {0};

    pid = fork();
    if (pid == -1) {
        perror("fork");
    }   
    if (pid == 0) {//child
        printf("[child]sleeping\n");
        sleep(2);//sleep to wait parent exit;
        write(1, "[child]nihao\n", 13);
        if (read(0, buf, 1) == -1) {
            printf("[child]ops, read error\n");
        }
        _exit(0);
    } else {
        printf("[parent]exit\n");
        //if (waitpid(pid, NULL, 0) < 0) {
        //     perror("waitpid error\n");
        //}
        _exit(9);   
    }   
}

该程序将输出:

Jason at Jason-ubuntu in ~/c/more
○ ./fd-on-close 
[parent]exit
[child]sleeping

Jason at Jason-ubuntu in ~/c/more
○ [child]nihao
[child]ops, read error

9423是孩子的PID

╰─○ ls -la /proc/9423/fd/
total 0
dr-x------ 2 sunan sunan  0 Oct 30 19:57 .
dr-xr-xr-x 9 sunan sunan  0 Oct 30 19:57 ..
lrwx------ 1 sunan sunan 64 Oct 30 19:57 0 -> /dev/pts/33
lrwx------ 1 sunan sunan 64 Oct 30 19:57 1 -> /dev/pts/33
lrwx------ 1 sunan sunan 64 Oct 30 19:57 2 -> /dev/pts/33

有一个thread问了同样的问题,但我想知道更多关于它的细节,比如如何强迫孩子控制终端,如何查看该线程中提到的progess组信息,以及谁控制了终端等等。

提前致谢!

1 个答案:

答案 0 :(得分:0)

父进程控制终端。子进程不控制终端。因此,父进程终止,子进程进入后台。并且init接受该子进程并将其添加到该子进程中。因此,只有孩子不控制终端。

如果你想这样做你可以使用tcsetpgrp函数来做孩子已经拿走控制终端。

如果父亲死亡,则session_leader接受终端控制。