首页 文章

在Linux中,fwrite命令没有设置errno,如何在失败的情况下获得正确的errno

提问于
浏览
1

从linux中的fwrite手册页,

DESCRIPTION 函数fread()从流指向的流中读取数据的nmemb元素,每个数据字节长,将它们存储在ptr给定的位置 .

The function fwrite() writes nmemb elements of data, each size bytes long, to the stream pointed to by stream, obtaining them from the location given by ptr.

   For nonlocking counterparts, see unlocked_stdio(3).

RETURN VALUE 成功时,fread()和fwrite()返回读取或写入的项目数 . 此数字等于仅在大小为1时传输的字节数 . 如果发生错误或达到文件末尾,则返回值为短项目计数(或零) .

fread() does not distinguish between end-of-file and error, and callers must use feof(3) and ferror(3) to determine which occurred.

Now my question is: 假设由于驱动器上没有空间而发生fwrite()系统调用失败 . 我们怎样才能得到它的错误 . 因为fwrite没有设置errno以防万一 .

Just in case errno is: 头文件定义整数变量errno,它由系统调用和一些库函数设置,如果发生错误则指示出现了什么问题 .

Talking in terms of Programming language: C.

3 回答

  • 1

    因为fwrite没有在出现故障时设置errno:不完全正确 . fwrite唯一可能的错误是在调用底层 write 系统调用期间可能发生的错误 . 在这种情况下,将设置errno变量,但 write 调用将可用,并且您将能够直接使用strerror或perror函数来获取错误的文本描述 .

    顺便说一句,fwrite是 not 系统调用但是标准库函数:是不直接调用内核函数 .

  • 1

    fwrite() 不是直接系统调用,通常通过 FILE * 指针完成的所有I / O都是缓冲的 . 无法保证对 fwrite() 的调用实际上会在当时执行写操作 . 可以立即返回错误,或者稍后使用 FILE * 调用函数 . 但是, fclose() 将写出任何剩余的缓冲数据,如果写入不成功,将返回错误 .

    总之,您需要在每次调用 fwrite()fread()fclose() 时检查错误 . 如果您想避免在任何地方进行错误检查,可以随时调用 ferror() 来检查 FILE * 的错误状态 .

    发生错误时设置变量 errno ,因为C库内部调用 read()write() ,并且出现错误时设置 errno .

  • 1

    fwrite() 由于EOF而无法失败,但fread()可以 .

    对于fwrite(),如果它没有写入您告诉它的相同数量的项目,则会发现错误,因此您可以像这样检查:

    size_t written = fwrite(buf, element_size, num_elements, file);
    if (written != num_elements) {
       //error , here errno do get set and you can inspect it/print it etc.
    }
    

    现在,FILE *有一个内部缓冲区,因此 fwrite() 调用可能实际上不会将数据写入操作系统或文件,除非该内部缓冲区已满 .

    这意味着您还需要 fflush() FILE *并在每次 fwrite() 调用后检查错误,如下所示:

    if (fflush(file) == EOF) {
           //error , here errno do get set and you can inspect it/print it etc.
    }
    

    或者您必须接受在您执行的任何未来调用时可能会给您带来潜在的写入失败,例如:那些调用碰巧自动刷新()FILE * . 调用 fclose() 时,您还必须检查错误:

    if (fclose(file) == EOF) {
           //error , here errno do get set and you can inspect it/print it etc.
    }
    

    对于 fread() ,您可以检查errno是否失败 . 处理完所有数据 fread() 之后,您可以执行此操作

    if (ferror(file)) {
         //error , here errno do get set and you can inspect it/print it etc.
    }
    

相关问题