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.
Related
Trying to understand :
C.2.9 Clause 19: diagnostics library [diff.cpp03.diagnostics]
19.4
Change: Thread-local error numbers
Rationale: Support for new thread facilities.
Effect on original feature: Valid but implementation-specific C++ 2003 code that relies on errno being the same across threads may change behavior in this International Standard.
I understand <error.h> content is in header <cerrno> but we have to define errno as a macro. Can anyone explain what we can do so that errno would act the same way as it was in C++03 during multi-threading?
You don’t need to change anything.
The change in the standard is purely because C++03 had no notion of threads, and the abstract machine model used by the standard to describe the semantics of standard C++ code needed to be updated for C++11 to support threads.
But the observable behaviour of errno in conforming C++ code stayed roughly the same, with the sole exception that errno is now defined thread-locally, and if your code assumes that the value of errno is the same across threads it will break.
C++11 us the first official standard that has a notion of multi-threading. This implies that if you use multiple threads in C++03 or C++98 you are using undefined behavior.
The whole idea about this change is about the following code:
functionThatSetsErrNo();
if (errno == something)
...
If you run this code and the execution results in functionThatSetsErrNo of thread 1, followed by functionThatSetsErrNo of thread 2, followed by the if-statements these if-statements do the right thing in C++11 and gave you a race condition in C++03 possibly combined with the errno of the second execution.
So what did change? If you after calling functionThatSetsErrNo started a thread, that thread no longer can read the errno value. Or similarly, if you have synchronization between threads and one calls the function and the other reads errno.
I hope this indicates that this change ain't too much to worry about as this delayed requesting of errno is something that is barely done and relying on transfer over threads is even done less.
If you do end up with this situation, you need to put a global std::atomic in your program and after execution assign errno into it while reading it from another thread. Although, I actually would recommend getting rid of such strange behavior.
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.
According to the boost reference for Boost.Iostreams (In section 3.6, at the very bottom):
http://www.boost.org/doc/libs/1_64_0/libs/iostreams/doc/index.html
Although the Boost.Iostreams Filter and Device concepts can
accommodate non-blocking i/o, the C++ standard library stream and
stream buffer interfaces cannot, since they lack a means to
distinguish between temporary and permanent failures to satisfy a read
or write request
However, the function std::istream::readsome appears to be non-blocking, in that the available characters will be immediately returned, without a blocking (except for a RAM copy) wait. My understanding is that:
std::istream::read will block until eof or number of characters read.
std::istream::readsome will return immediately with characters copied from the internal buffer.
I agree with you that readsome is not a blocking operation. However, as specified, it is wholly inadequate as an interface for performing what is usually called "non-blocking I/O".
First, there is no guarantee that readsome will ever return new data, even if it is available. So to guarantee you actually make progress, you must use one of the blocking interfaces eventually.
Second, there is no way to know when readsome will return data. There is no way to "poll" the stream, or to get a "notification" or "event" or "callback". A usable non-blocking interface needs at least one of these.
In short, readsome appears to be a half-baked and under-specified attempt to provide a non-blocking interface to I/O streams. But I have never seen it used in production code, and I would not expect to.
I think the Boost documentation overstates the argument, because as you observe, readsome is certainly capable of distinguishing temporary from permanent failure. But their conclusion is still correct for the reasons above.
When looking into non-blocking portability, I didn't find anything in the C++ standard library that looked like it did what you think it does.
If your goal is portability, my interpretation was that the section that mattered most was this:
http://en.cppreference.com/w/cpp/io/basic_istream/readsome
For example, when used with std::ifstream, some library
implementations fill the underlying filebuf with data as soon as the
file is opened (and readsome() on such implementations reads data,
potentially, but not necessarily, the entire file), while other
implementations only read from file when an actual input operation is
requested (and readsome() issued after file opening never extracts any
characters).
This says that different implementations that use the iostream interface are allowed to do their work lazily, and readsome() doesn't guarantee that the work even gets kicked off.
However, I think your interpretation that readsome is guaranteed not to block is true.
I want to use boost::asio but I don't want boost to throw exceptions, because in my environment exceptions must not be raised.
I've encountered BOOST_NO_EXCEPTIONS but the documentation says that callers of throw_exception can assume that this function never returns.
But how can a user supplied function not return? What replacement function would I need to insert here? Do I have to terminate the process in case boost code wants to throw an exception?
Well, what do you want to do on error condition? BOOST_NO_EXCEPTION does not magically make Boost source code use alternative mechanism of propagating error back to callers. So, you either print an error to stderr and die, or you longjmp all the way to the top -- leaking whatever resources the functions presently on the call stack might have allocated.
Either you terminate the process or you goto a something like a global error handler using longjmp which you've previously defined with setjmp.
You seemed to have misunderstood the meaning of BOOST_NO_EXCEPTIONS, it only gives you a chance to bailout in the way you desire in a consistent manner.
The execution has entered a state where it can no more proceed, that is when exception is thrown, so if the user defined throw_exception returns then it is logical to think that the behavior is undefined.
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.