我正在编写一个围绕通用文件操作的包装器,并且当write返回一个较小的写入然后提供的大小时,不知道如何处理这种情况。
写的手册页说:
例如,如果底层物理介质上没有足够的空间,或遇到RLIMIT_FSIZE资源限制(请参阅setrlimit(2)),或者调用被中断,则写入的字节数可能小于count。写入少于count个字节后的信号处理程序。 (另见管道(7)。)
根据我对上述内容的理解,它是错误(中等完整)和煽动回来(中断呼叫)的混合。如果我的文件描述符都是非阻塞的,我不应该得到中断的情况,然后唯一的原因就是错误。我是对的吗?
代码示例:
int size_written = write(fd, str, count);
if (size_written == -1) {
if (errno == EAGAIN) {
// poll on fd and come back later
} else {
// throw an error
}
} else if (size_written < count) {
// ***************
// what should I do here ?
// throw an error ?
// ***************
}
答案 0 :(得分:2)
您需要在循环中使用原始I / O函数:
ssize_t todo = count;
for (ssize_t n; todo > 0; )
{
n = write(fd, str, todo);
if (n == -1 && errno != EINTR)
{
// error
break;
}
str += n;
todo -= n;
}
if (todo != 0) { /* error */ }
有关EINTR
的特殊条件允许写入调用被信号中断,而不会导致整个操作失败。否则,我们希望最终能够写入所有数据。
如果您无法完成所有数据的写入,因为您的文件描述符是非阻塞的,并且此刻无法接受任何数据,则必须存储剩余的数据,并在文件描述符发出信号表明已准备好之后再次尝试再写一次。