损坏管道上的发送行为

Posted

技术标签:

【中文标题】损坏管道上的发送行为【英文标题】:Send behavior on Broken pipe 【发布时间】:2010-07-05 20:57:29 【问题描述】:

在编写一个简单的服务器-客户端应用程序时,我想到了这个问题。当有人尝试写入损坏的管道时,会生成一个 SIGPIPE。假设我在代码中处理信号。

现在 write 调用返回什么错误 - EPIPE 或 EINTR(因为它被信号中断了)。我尝试了一个示例程序,我似乎总是得到 EPIPE。这是有保证的行为还是可能是两个错误值中的任何一个?

【问题讨论】:

【参考方案1】:

POSIX 说应该返回 EPIPE 并发送 SIGPIPE:

用于写入管道或 FIFO 的 write()s 或 pwrite()s 未打开以供任何进程读取,或仅打开一端。 对于不再连接或关闭以进行写入的套接字的 write()。

你可以看看 POSIX 标准here

【讨论】:

【参考方案2】:

write(2) 调用在错误时返回-1,所以我猜你是在询问errno(3) 的值。

如果您处理阻止忽略信号,您将获得EPIPE。否则进程默认终止,见signal(7)

【讨论】:

【参考方案3】:

一般来说,“被信号中断”(EINTR)是指完全荒谬的 Unix System V 信号处理,如果您的进程在期间接收(并处理)信号,ANY 系统调用可能会失败系统调用。这需要用do ... while (ret==-1 && errno==EINTR); 或类似的东西包装每个系统调用。虽然 POSIX 仍然允许这种行为或良好(“BSD”)行为,但像 GNU/Linux 这样的健全系统默认具有 BSD 行为。您始终可以通过使用正确的参数调用 sigaction 来获得 BSD 行为,甚至可以为您创建一个包装函数。

因此,EINTR 与写入错误导致的 SIGPIPE 无关。

【讨论】:

以上是关于损坏管道上的发送行为的主要内容,如果未能解决你的问题,请参考以下文章

管道多个命令进行bash,管道行为问题

redis事务与管道区别

尝试通过运行 Tkinter 的发送进程在进程之间通过管道发送任何内容时出现管道损坏错误

连接损坏后 ResultSet 的行为

Azure 数据工厂:执行管道活动无法引用调用管道,需要循环行为

Mediatr 行为管道中的验证