【问题标题】:Why is explain_fwrite saying my file marked as non-blocking?为什么 explain_fwrite 说我的文件标记为非阻塞?
【发布时间】:2021-10-25 21:47:48
【问题描述】:

我正在尝试将一些数据写入文件。 fwrite 正在返回 EAGAIN 并且 fwrite_explain 说:

2: fwrite(ptr = 0x7F41EFBC09A8, size = 4066, nmemb = 1, fp = 0x02F79200 "/home/user/asdf.txt") failed, Resource temporarily unavailable (11, EAGAIN) because the file descriptor has been marked non-blocking (O_NONBLOCK) and the write would block
2: fwrite(ptr = 0x17ECFFA40, size = 4066, nmemb = 1, fp = 0x02F79200 "/home/user/asdf.txt") failed, No such file or directory (2, ENOENT) because the file is on a file system ("/home", 1% full) which does not support Unix open file semantics, and the file has been deleted from underneath you
2: fwrite(ptr = 0x17ECFF100, size = 4066, nmemb = 1, fp = 0x02F79200 "/home/user/asdf.txt") failed, No such file or directory (2, ENOENT) because the file is on a file system ("/home", 1% full) which does not support Unix open file semantics, and the file has been deleted from underneath you

我假设第二组警告无效(文件永远不会被删除,它仍然存在)。

我从不将我的文件设置为非阻塞,我不在乎它是否阻塞,因为我想写入数据,不管它可能需要多长时间。什么给了?

相关代码:

fd = fopen(file_to_write, "w");
if (fd == NULL) printf("%d could not open file\n", errno);
n = fwrite((void*)h->bufs[i], write_size, 1, fd);
if (n != write_size) {
    printf("%d: %s\n", errno, explain_fwrite((void*)h->bufs[i], write_size, 1, fd));

【问题讨论】:

    标签: c fwrite


    【解决方案1】:

    fwrite() 返回写入的 items 数量,而不是一个项目的 size 或两者的乘积。 (仅当一项的大小恰好为 1 时,返回值才等于写入的字节数。)

    解决方案是与您尝试编写的项目数量进行比较:

    n = fwrite((void*)h->bufs[i], write_size, 1, fd);
    if (n != 1) {
    

    注意:在调用之前将errno 设置为零可能是明智的,因为如果函数没有错误,它不会设置为零。

    【讨论】:

    • 观察力不错。而且由于fwrite在没有发生错误时不会触及errno,所以OP观察到的值只是最后一次遇到错误的系统调用留下的值,与fwrite本身无关.
    • 而不是将errno 设置为0,在大多数情况下,最好的做法是仅在您知道确实发生了错误时才查看其值(如返回值所示)。
    • 这也解释了 OP 自己的答案:交换 sizenmemb 不会改变写入的完成方式,但会影响返回值,因此测试 if (n != write_size) 变得正确.
    • Fwrite 意味着如果返回的值不是大小(并且没有命中 EOF),那么就会发生错误,因此除了 nmemb 混淆之外,检查可以说是正确的。然而,在第一种情况下写入没有发生(文件为空),尽管 fwrite 说它确实写入了一个完整的成员。
    • @BrydonGibson 你是如何检查书面文件的?检查之前是否关闭或刷新文件流?
    【解决方案2】:

    我在发布这个的过程中设法解决了这个问题。原来fwrite 对 size 和 nmemb 的顺序和内容很挑剔。我想我可以写一个 非常大的成员,但它不是这样工作的。我必须以一个字节的大小写write_size 成员。

    【讨论】:

    • 该分析使man 3 fread 文档变得毫无意义,指出"This number equals the number of bytes transferred only when size is 1." fwrite() 不在乎size 是否是122484096size = 1 仅与比较 returnfwrite() 相关,这听起来更像是您有几个进程同时以某种方式访问​​了 asdf.txt
    • 这样的话,是不是还有一个错误呢?即使我正在写一个成员,写入也会失败
    • fwrite( ... "/home/user/asdf.txt") failed, Resource temporarily unavailable ... 指向的不是您使用fwrite() 的问题,而是"/home/user/asdf.txt" 的“不可用”问题。这就是让我怀疑其他一些进程也在使用该文件的原因,并且在它对文件执行任何它需要做的事情时对文件进行了锁定。鉴于可用的信息,不可能说出那是什么。我会使用 fuser /home/user/asdf.txt 来查看还有什么(如果有的话)正在使用该文件。
    • @DavidC.Rankin 该文件没有锁,除了我自己之外没有其他任何东西在使用这些文件(在这种情况下我正在创建文件)。有趣的是,当我尝试 rm 文件时,它显示为“写保护”。不确定这是否相关
    • 是的,这指向一个直接相关的问题。显示ls -al /home/user/asdf.txt,让我们看看文件权限和UID/GID。确保您拥有该文件并在第一个八位字节中具有写入权限,或者您是该组的成员并且在第二个八位字节中具有写入权限,或者无论所有权如何,在第三个八位字节中都有写入权限。您还必须对目录 /home/user/ 具有执行权限,否则您缺乏“下降到”该目录所需的权限。
    猜你喜欢
    • 2012-10-31
    • 2011-04-24
    • 2016-11-06
    • 2017-04-26
    • 2018-11-15
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多