Reputation: 974
From man page of fwrite in linux,
DESCRIPTION The function fread() reads nmemb elements of data, each size bytes long, from the stream pointed to by stream, storing them at the location given by 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 On success, fread() and fwrite() return the number of items read or written. This number equals the number of bytes transferred only when size is 1. If an error occurs, or the end of the file is reached, the return value is a short item count (or zero).
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: Suppose fwrite() system call failure occurred due to No space on the drive. How can we get the errno for it. As fwrite is not setting the errno in case of failure.
Just in case errno is: The header file defines the integer variable errno, which is set by system calls and some library functions in the event of an error to indicate what went wrong.
Talking in terms of Programming language: C
Upvotes: 2
Views: 3846
Reputation: 229058
fwrite()
cannot fail due to EOF, but fread() can.
For fwrite(), you discover an error if it did not write the same amount of items you told it to, so you check it like this:
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.
}
Now, a FILE* have an internal buffer, so a fwrite()
call might not actually write the data to the operating system or file unless that internal buffer gets full.
This means you also either have to fflush()
the FILE* and also check for errors after each fwrite()
call like so:
if (fflush(file) == EOF) {
//error , here errno do get set and you can inspect it/print it etc.
}
Or you have to accept that a potential write failure can be given to you on any future fwrite()
calls you perform if e.g. those calls happens to flush() the FILE* automatically.
And you'd also have to check for errors when calling fclose()
:
if (fclose(file) == EOF) {
//error , here errno do get set and you can inspect it/print it etc.
}
For fread()
you can inspect errno if it failed. After you have handled any data an fread()
call have read, you can do
if (ferror(file)) {
//error , here errno do get set and you can inspect it/print it etc.
}
Upvotes: 2
Reputation: 7973
fwrite()
is not a direct system call, and in general all I/O done via a FILE *
pointer is buffered. There is no guarantee that a call to fwrite()
will actually perform a write at that time. Errors can be returned immediately, or by later calls to functions using FILE *
. However, fclose()
will write out any remaining buffered data, and will return an error if that write did not succeed.
In summary, you need to check for errors during every call to fwrite()
, fread()
and fclose()
. If you want to avoid doing error checking everywhere, you can call ferror()
at any time to check the error status of a FILE *
.
The variable errno
is set when errors occur, because the C library internally calls read()
and write()
, and those set errno
in case of errors.
Upvotes: 2
Reputation: 148870
As fwrite is not setting the errno in case of failure: not exactly. The only possible error for fwrite is an error that would occur during the call of the underlying write
system call. In that case the errno variable will be set but the write
call and as such will be available, and you will be able to directly use the strerror or perror functions to get a textual description of the error.
BTW, fwrite is not a system call but a standard library function: is does not directly call a kernel function.
Upvotes: 1