Why is explain_fwrite saying my file marked as non-blocking?

Viewed 75

I'm trying to write some data to a file. fwrite is returning EAGAIN and fwrite_explain says:

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

I assume the second set of warnings are invalid (the file never gets removed, it's still there).

I never set my file as non-blocking, and I don't care if it blocks because I want to write the data, regardless of how long it may take. What gives?

The relevant code:

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));
2 Answers

fwrite() returns the number of items written, not the size of one item or the product of both. (Only if the size of one item happens to be 1, the return value is equal to the number of bytes written.)

The solution will be to compare against the number of items you try to write:

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

Note: It might be wise to set errno to zero before a call, as it is not set to zero if the function has no error.

I managed to solve this in the process of posting this. Turns out fwrite is picky about the order and contents of size and nmemb. I figured I could write one really big member, but that's not how it works. I have to write write_size members each at one byte in size.

Related