如何检查标准输出是否已关闭

mon*_*ing 6 c unix

我得到了一些打印到stdout的代码,伪代码看起来像

int main(){
    //allocate data
    while(conditional){
      char *string = makedata();
      fprintf(stdout,"%s",string);
    }
    //cleanup 
}
Run Code Online (Sandbox Code Playgroud)

这种方法很好,如果条件切换为零,但如果我管道输出像

./a.out |head -n10 >dumped
Run Code Online (Sandbox Code Playgroud)

然后代码永远不会到达清理部分,我不明白如何检查stdout是否关闭.

谢谢

Rob*_*obᵩ 5

你的标准输出还没有关闭,所以检查它是没用的.您的计划已收到SIGPIPE并退出.只要您的程序写入没有读取器的管道,就会提供SIGPIPE.在您的示例中,当head退出时关闭其stdin 时会发生这种情况.

如果希望程序继续,则应忽略SIGPIPE.此代码将忽略SIGPIPE:

(void)signal(SIGPIPE, SIG_IGN);
Run Code Online (Sandbox Code Playgroud)

如果您不想修改程序,可以安排从管道继续读取内容,即使在head关闭其输入后也是如此.1

./a.out | ( head -n10 >dumped ; cat > /dev/null )
Run Code Online (Sandbox Code Playgroud)

1 :shell示例对bash有效,也许不适用于csh.

  • @WilliamPursell - 不,管道的*另一端已经关闭。写入远端关闭的管道或套接字文件描述符的操作会生成 SIGPIPE。写入已关闭的文件描述符的行为会生成 EBADF。 (2认同)