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

标签 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是 child 的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问了同样的问题,但我想知道更多细节,比如如何强制 child 控制终端,如何查看该线程中提到的进程组信息,以及谁在控制终端等

提前致谢!

最佳答案

父进程控制终端。子进程不控制终端。因此,父进程死亡,子进程进入后台。 init 获取该子进程并将其添加到该子进程中。所以,只有 child 不控制终端。

如果你想这样做,你可以使用 tcsetpgrp 函数来让 child 使用控制终端。

如果 parent 去世,session_leader 将获得终端控制权。

关于父进程退出后,子进程无法从终端读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33435636/

相关文章:

bash - find -exec 的变量包含带有引号的 codesign 命令

bash - 如何使用 ADF 在数据 block 中安装 jar

bash - shell 如何检测终端是否支持颜色

c - 如何在函数中动态分配数组?

linux - LL_ALLOCATED_SPACE 和其他注意事项

linux - 在 Ubuntu 12.10 32 位上安装 WKHTMLTOPDF

linux - 如何将实际变量传递到 bash 中的文本文件?

c - 为什么灵活数组成员必须位于结构的末尾,但具有灵活数组的结构则不然?

c - 使用指针搜索特定字符串

c - C物理程序中的不规则行为