【问题标题】:What should I do when write returns smaller size?当 write 返回较小的大小时我该怎么办?
【发布时间】:2014-03-04 01:29:33
【问题描述】:

我正在为通用文件操作编写一个包装器,但不知道如何处理当 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 ?
  // ***************
}

【问题讨论】:

    标签: c++ system posix unistd.h


    【解决方案1】:

    您需要在循环中使用原始 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 的特殊条件允许写入调用被信号中断,而不会导致整个操作失败。否则,我们希望最终能够写入所有数据。

    如果由于文件描述符是非阻塞的并且目前无法接受任何数据而无法完成所有数据的写入,则必须存储剩余的数据并稍后在文件描述符发出信号时重试再写一遍。

    【讨论】:

    • 感谢您的解释。我觉得应该稍微改一下:for (ssize_t n; todo; )
    猜你喜欢
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多