防止SIGPIPE

3
让我们考虑以下例子。
我有一个父进程,创建了一个管道,生成一个子进程,并使用该管道读取子进程的标准输出。在某个时刻,父进程不再关心子进程的输出,并关闭管道的读端。
显然,如果子进程继续写入,那么这将导致子进程接收到SIGPIPE信号。
问题:是否有一种方法将子进程的输出重定向到/dev/null,以便它仍然可以继续运行和产生输出,但是父进程可以继续做其他事情并稍后调用waitpid来等待子进程?请注意,设置子进程的SIGPIPE处理程序为SIG_IGN不是一个选项,因为我无法控制子进程的信号处理程序。

Gergely和sarnold的建议基本上是正确的。但请注意,SIGPIPE的存在是有原因的:如果没有它,生成输出的进程将一直旋转到输入的末尾(可能是永远),而不是退出——像“more”或“head/tail”这样的工具将无法编写。您真的确定这是您想要的行为吗? - Andy Ross
3个回答

2

自己模拟 /dev/null -- fork() 一个新进程,其任务是读取并忽略子进程的输出。


1
请注意,将子进程的SIGPIPE处理程序设置为SIG_IGN不是一个选项,因为我无法控制子进程的信号处理程序。
将其包装在一个简单的二进制文件中。(顺便说一句,即使是shell脚本也可以。)

1
这将防止 SIGPIPE 导致的程序崩溃,假设子进程没有重置其信号处理程序为 SIG_DFL。但是,它将从 write() 收到 EPIPE 错误,可能会导致其抱怨并退出。 - Alan Curry
虽然我很难想象一个不断运行但被忽略的孩子应该做什么 :) - sarnold
1
@sarnold:嗯,在最后,你可以在一个chroot环境下做一个nohup binary.bin > /dev/null < /dev/zero,最好是在Xen下:D 这将是终极的“不听不看不说话”的程序 :) - Gergely Szilagyi
fork()返回0之后,在执行子进程之前,您可以将SIGPIPE设置为SIG_IGN。假设子进程没有显式地重置它,那么子进程将永远不会收到SIGPIPE信号。(尽管像Alan提到的那样,它的写入将得到EPIPE错误。) - mark4o

0

Sigpipe发生在两个组件之间的管道断裂时。

您可以通过以下方式忽略sigpipe

signal(SIGPIPE, SIG_IGN);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接