【问题标题】:What should I do when write(fd, buf, count) returns 0? [duplicate]write(fd, buf, count) 返回0怎么办? [复制]
【发布时间】:2011-04-13 22:51:03
【问题描述】:

可能重复:
Is a return value of 0 from write(2) in C an error?

假设计数 > 0:

ret = write(fd, buf, count);  
if(ret == 0) {  
    // Should I try to write again
    // or treat this as error?
}

有没有可能出现这种情况的情况?

【问题讨论】:

  • 当π为3时我该怎么办? :-)

标签: c linux unix


【解决方案1】:

除非您明确地将零长度传递给write,否则这将永远不会在正确的、符合 POSIX 的系统上发生。如果您想支持各种晦涩难懂的损坏的遗留专有单元,您可能必须调查每个单元上发生的情况,以及返回值为零是出现在EINTR 的位置还是EWOULDBLOCK 的位置或其他一些错误...

就我个人而言,2011 年我只是假设它不会发生。还有很多其他的东西会破坏得更糟,试图支持这些破旧的垃圾..

注意,根据 POSIX:

如果 write() 在写入任何数据之前被信号中断,它应返回 -1 并将 errno 设置为 [EINTR]。

http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

【讨论】:

  • 谢谢。另请注意,对于您可能遇到的所有其他常见错误情况(连接关闭、磁盘已满、超出资源限制……)POSIX 表示write 将失败。我认为它可能逃脱返回零的唯一方法是在任何指定的强制错误条件范围之外的其他实现定义的条件下,但这将是一个很大的延伸。
  • “这在正确的、符合 POSIX 的系统上永远不会发生”——您能否提供一个链接来证明这一说法?
  • Linux 说如果大小为 0 并且没有任何错误,它将返回 0。我查看了它是否可以返回 0。 (所以即使是非阻塞也不会返回 0?)
  • @PaulStelian:如果无法写入任何内容,则非阻塞返回 -1 和 EAGAIN。阅读上述 POSIX 链接的基本原理中的历史注释。很久很久以前,在 POSIX 之前,一些系统返回 0 而不是 EAGAIN,但明确禁止这样做。
  • @R.. 所以我明白了。然后在我的代码中,如果以某种方式返回 0,我将只放置一个错误路径(将某些内容打印到标准错误,然后继续 - 因为否则我无法取悦作业检查器)
【解决方案2】:

write 系统调用的结果是该系统调用写入的总字节数。在所有错误情况下,它将返回 -1。因此,如果函数返回 0,我们处于未定义状态(基于通用文档)。我会寻找任何平台特定的理由来返回 0 并根据该研究的结果进行处理。如果您没有找到特定于平台的原因,我会退出。您遇到了来自系统调用的未定义行为,这不好。

手册页:http://linux.die.net/man/2/write

【讨论】:

  • write 确实可以返回小于计数的值,但是除非计数为 0,否则它不能返回 0 —— 这样做完全是浪费时间,并且有无限循环的风险。检查 0 的返回值并设置计时器以及所有会使每个 C 程序复杂化的事情,绝对没有理由。
  • 问题在于行为未定义。文档说它不应该发生,但他们也说任何错误都会返回 -1,因此如果它以某种方式返回 0,那么我们处于未定义状态。因此,我会说立即退出系统调用的未定义行为是最好的选择。
  • 解释系统调用未定义行为的用户代码是非常糟糕的代码。您不妨考虑系统返回国歌而不是文件内容。
【解决方案3】:

您的问题已被提出并讨论过。 :) 希望this 页面有所帮助。

【讨论】:

    【解决方案4】:

    根据writeman 页面,您应该检查errno

    【讨论】:

    • 根据this,如果有错误,ret 应该是-1。 (啊,没关系。我读了解释为什么你会收到 0 的欺骗。)
    • 手册页没有具体说明这个问题。
    • 如果write 没有返回-1...
    • @Michael 受骗者在哪里解释了为什么您会收到 0?事实上,除非计数为 0(或实现有问题),否则您无法收到 0。 R.. 是对的——如果 write 返回 0,则 errno 的值是未定义的,所以我认为这是一个错误(和危险)的答案。
    • @R.: 好吧,除非你在调用write()之前把它设置为零。
    猜你喜欢
    • 2015-06-11
    • 2015-04-14
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    相关资源
    最近更新 更多