c - POSIX 部分 write() 和信号中断
问题描述
从手册页write()
请注意,成功的 write() 可能传输少于 count 个字节。这种部分写入可能由于各种原因而发生;例如,因为磁盘设备上没有足够的空间来写入所有请求的字节,或者因为阻塞的 write() 到套接字、管道或类似的东西在传输一些字节之后被信号处理程序中断,但在它之前已传输所有请求的字节。在部分写入的情况下,调用者可以进行另一个 write() 调用以传输剩余的字节。随后的调用将传输更多字节或可能导致错误(例如,如果磁盘现在已满)。
我有以下问题
1) 在write()
部分传输后被信号处理程序中断的情况下,write() 将设置errno
为EINTR
?
2)如果errno
没有设置,有没有办法在没有额外代码的情况下识别这样的事件(比如安装信号配置并将标志值设置为true
)?
注意:在信号中断事件发生后,进一步的write()
调用成功地传输了剩余的字节。
解决方案
要回答您的个人编号问题:
errno
仅在其中一个标准函数返回一个指示错误的值之后才有意义 - forwrite
, -1 - 并且在任何其他可能破坏它的标准函数或应用程序代码被调用之前。所以不,如果write
返回一个短写,errno
将不会被设置为任何有意义的东西。如果它等于EINTR
,它恰好是;这不是您可以解释的有意义的事情。识别此类事件的方法是返回值严格小于
nbytes
参数。这实际上并没有告诉你短写的原因,所以它可能是其他的东西,比如空间不足。如果您需要知道,您需要安排信号处理程序通知您。但在几乎所有情况下,您实际上并不需要知道。
关于注释,如果在信号到达后write
返回完整nbytes
,则信号处理程序是非中断的。这是 Linux 上任何现代 libc(glibc、musl,基本上除了 libc5 之外的任何东西)的默认设置,而且它几乎总是正确的。如果您确实想要中断信号,则必须安装信号处理程序sigaction
并SA_RESTART
清除标志。(相反,如果您要安装信号处理程序,则希望具有正常、合理、不中断的行为,为了可移植性,您应该使用sigaction
并设置SA_RESTART
标志而不是使用旧功能signal
)。
推荐阅读
- javascript - 如何删除 div 中的最后 3 个 div
- java - 如果第一个接口定义了它,为什么我不能在另一个接口中使用实现类作为参数?
- javascript - JS:Image onerror 上的无用循环——有什么用?
- excel - Remove decimal by VBA from a cell in Excel 2010
- ios - 以编程方式创建 UItextfield,以后如何在 Swift 中获取文本?
- google-chrome - Chrome 网上应用店 (CWS) API 付款 TOKEN_MISSING_ERROR
- excel - Accessing a text box on a worksheet multipage object (Not a VBA userform)
- angular - angular-google-charts:解析 x 属性的意外值 NaN
- firebase - Bootstrap Vue + Nuxt JS modal problem inside v-for
- python-3.x - AttributeError: module 'pandas' has no attribute 'read_csv' in python 3.6