If a call to fread() returns 0 and ferror() indicates an error (vs. EOF), is it OK to retry the read or is it better to close and reopen the file?
I can't start over entirely -- the input file has been partially processed in a way that can't be undone (say I'm writing out a chunk at a time to a socket and, due to existing protocol, have no way of telling the remote end, "never mind, I need to start over").
I could fclose() and fopen() the file, fseek() past the data already processed, and continue the fread()-ing from there, but is all that necessary?
There's no "one size fits all" solution, since different errors can require different handling. Errors from fread() are unusual; if you're calling it correctly, an error may indicate a situation that has left the FILE* in a weird error state. In that case you're best off calling fclose(), fopen(), fseek() to get things back in a good state.
If you're coding for something that's happening, please mention the actual errors you're getting from ferror()...
You can give the clearerr function a look.
You can show the error to the user with perror() or strerror() and ask her is she wants to retry.
It's not mandatory for the implementation to provide such an error message, though. You should set errno to 0 before calling fread(); if it fails and errno is still 0 then no error information will be available.
Related
Once I have enabled O_NONBLOCK, and then call a non-blocking function, and after it returns some I/O error happens, how may I get to know that something bad has happened, and how to handle it?
You get the errors when they are ready for you to see them and you are ready to receive them.
sooner or later you end up calling read() or close() or whatever and that will give you the error.
In writing a C++ Windows application, I'm using the SymInitializeW to initialize the symbols for getting a backtrace. As the documentation mentions, I'm checking the return code, and then using GetLastError and FormatMessage when SymInitializeW returns false (like in the example).
However, I'm getting an error message of "The data area passed to a system call is too small" when I do so. I'm not sure what that's referring to, as there really isn't a "data area" being passed - just the process handle, the PCWSTR for the search path, and the bool. -- It's doubly confusing as it seems like the symbol loading works. (e.g. if I skip the error handling, things seem to work properly.)
Does this message point to something I'm actually doing wrong, or is it spurious? If spurious, why is SymInitializeW returning false?
The SymInitialize functions should only be called once on a given process handle. If there's any code path in which a SymInitialize function can be called multiple times, you may get odd errors like "The data area passed to a system call is too small" (ERROR_INSUFFICIENT_BUFFER, 122 (0x7A)) or "The parameter is incorrect" (ERROR_INVALID_PARAMETER 87 (0x57)) and potentially others from GetLastError, despite the fact that you're using all the correct parameters according to the documentation. (There isn't necessarily a specific "Don't call SymInitialize twice" error.)
Best practice is to make sure the control flow through your symbol-handling functions is clear, and that you call SymInitialize once and only once at the top, and then call SymCleanup on the process handle prior to exiting the functions that are doing symbol handling. If you've properly called SymCleanup, subsequent calls to SymInitialize should succeed.
I'm trying to figure out the reason of a failed ofstream::close() and encountered some behaviour I don't understand.
I use an std::ofstream and std::copy() to write data to a stream, then I write the file by using close(). If I provoke an error (e.g. the filesystem is full), the failbit is set by close(), but I'd like to get a more detailed error description.
So far I thought that errno is always set if a system call fails. However errno says Success if I check instantly after close() fails.
I'm sure a system call is used when close()ing the stream because it will write the file to the filesystem, but then how is it possible that errno doesn't tell anything about the problem? So:
Does ofstream::close() not use any system calls?
If I explicitly call flush() after std::copy(), then errno is set properly
No space left on device
and the failbit is set. The subsequent call of close() also sets the failbit. Surprisingly errno is reset to success.
As per errno manpage:
errno is never set to zero by any system call or library function
and I don't see which other function would reset errno.
Does ofstream::close() explicitly reset errno in case it succeeds?
The documentation on ofstream I've found doesn't say anthing about errno.
Tested with Linux x86 g++ 4.7.3.
Indeed ofstream::close() makes multiple system calls. Even though system calls and C library functions do not set errno to zero, C++ libraries may. At least some implementation of ofstream::close() sets errno to 0. See the comment below.
My advice is to pay attention to the documentation on the things you use, and do not make assumptions. In this case, as you pointed out the documentation of ofstream::close() does not say anything about errno, so you should not make any assumption of errno after calling ofstream::close(). On the other hand, C functions such as close(fd) specifically mention errno in the documentation. So if you really need errno, use C functions instead.
I'm writing a VC++ application. Just for the sake of argument, what could cause the ResetEvent API to fail? The Microsoft documentation is not clear on this. Thanks.
Most commonly an invalid handle will cause this to fail. An invalid handle, in turn, could result from:
the handle being closed by another process or thread prematurely
passing gobbledy-gook to ResetEvent()
Passing a handle to a thing that isn't an even
Number 1 can often be avoided by creating a duplicate of the handle, by calling DuplicateHandle().
GetLastError() generally will tell you exactly what the problem is, or at least point you in the direction.
Without access to the source of Windows we can only guess. Here's my guess at what could go wrong:
The handle is not a valid handle to an event object.
The handle does not have the necessary access rights. The documentation states that the handle must have the EVENT_MODIFY_STATE access right.
The OS runs out of memory or has some other critical failure.
Reading the WINE source reveals no other explicit failure modes.
Going thorugh overflow function documentation. I found overflow has following as return values.
Return Value:
A value different than EOF (or traits::eof() for other traits) signals success.
If the function fails, either EOF (or traits::eof() for other traits) is returned or an exception is thrown.
source :"http://www.cplusplus.com/reference/iostream/streambuf/overflow/"
Can anyone please tell me in which sceanrios is overflow function going to through an exception?
Any help will be appreciated
Streambuf is abstraction for stream's underlying storage or communication channel. The overflow() function can fail for any reasons the storage or channel can fail. E.g. disk error for disk files, broken connection for sockets etc.
Although wilx detailed the fail (EOF) condition, the exception condition can be either one of these: http://www.aoc.nrao.edu/php/tjuerges/ALMA/STL/html-3.4.6/classstd_1_1exception.html (can you guess which one? :) -- but it should (obviously) be std::overflow_error if you're writing your own output stream or something.
In my problematic scenario it was faling because it was not jumping the next address(setp calls was incrementating by 0) so retrying to use the same memory region and was giving segmentation fault.