C 如果从管道读取数据时尾部出现故障怎么办

C 如果从管道读取数据时尾部出现故障怎么办,c,unix,pipe,stderr,tail,C,Unix,Pipe,Stderr,Tail,因此,与上面的链接相关,我有一个孩子正在执行tail,而家长正在通过管道读取其输出 dup2(pipefd[1], STDOUT_FILENO); dup2(pipefd[1], STDERR_FILENO); 我的问题是,如果tail以某种方式失败,我正在读取的管道会发生什么情况?我在stderr上有什么消息吗?tail是否自行终止?或者它可能挂在那里,因为已失效?当tail终止时,内核将向管道上的另一个进程发送SIGPIPE信号。此信号的默认操作(如果未安装处理程序)是终止进程 如果不想处

因此,与上面的链接相关,我有一个孩子正在执行
tail
,而家长正在通过
管道读取其输出

dup2(pipefd[1], STDOUT_FILENO);
dup2(pipefd[1], STDERR_FILENO);

我的问题是,如果
tail
以某种方式失败,我正在读取的管道会发生什么情况?我在
stderr
上有什么消息吗?
tail
是否自行终止?或者它可能挂在那里,因为
已失效

tail
终止时,内核将向管道上的另一个进程发送
SIGPIPE
信号。此信号的默认操作(如果未安装处理程序)是终止进程


如果不想处理信号,可以忽略父级中的
SIGPIPE
(这样当
tail
终止时,它不会终止),而是在每次
读取
后检查
errno
的值是否为
EPIPE
。此外,您必须从父级调用
wait
waitpid
,以获取僵尸子级。

如果读取时未获得EPIPE,则只有write将返回EPIPE。您将得到EOF,由read返回0表示,并且由于您读取了stderr,因此也将得到错误消息(在EOF之前)


进程将变成僵尸,您可以使用wait/waitpid获取退出状态,如果出现错误,退出状态将为非零。

如果tail失败,管道读取端的任何读取都将返回EOF。如果tail失败,它已经终止,“失败”的定义是它以非零退出状态终止。它将保留在进程表中(即“已失效”),直到父进程等待它


但是为什么你让tail对stderr和stdout使用相同的管道呢?为什么不做两根管子呢?这似乎可以消除区分两个输出流的问题。

因为它们是重复的,我认为关闭一个的子级也会关闭另一个,导致后续对另一个的写入失败。父级将获得文件的结尾。但我不是100%肯定。@wberry:事实上,关闭是一件可以使用复制文件描述符而不影响其其他别名的事情。谢谢。我只想了解为什么SIGPIPE是一个古老的、几乎是历史性的Unix约定,但至今仍在使用。尽管如此,您仍然可以忽略
SIGPIPE
,并检查
errno
是否在父级中的
read
之后是
EPIPE
。SIGPIPE不是在管道关闭时发送的,而是在尝试写入另一端时发送的。谢谢,我相信,现在我甚至不需要读取
stderr
。如果
tail
失败,
stdout
将获得
EOF
,对吗?无论如何,我都在等待孩子。所以,它会被清理干净。听起来对吗?