Does stdio always set errno?
Asked Answered
S

2

10

When a stdio stream encounters an error (but not EOF), the stream's error indicator will be set so that ferror() will return nonzero. I have always assumed that more information is available in errno. But how do I know this?

Documentation for some functions [e.g. man fopen under Linux] says that errno will also be set. However man fgets doesn't mention errno at all. The glibc info pages are reassuring:

In addition to setting the error indicator associated with the stream, the functions that operate on streams also set `errno' in the same way as the corresponding low-level functions that operate on file descriptors.

But I have no idea how strong this guarantee is. Is it required by the C standard? What happens in Visual C/C++?

Sennight answered 20/5, 2012 at 8:55 Comment(0)
O
6

The C Standard itself does not require much use of errno WRT to stdio functions; it specifies ferror() but says of it only that

7.13.10.3 The ferror function The ferror function tests the error indicator for the stream pointed to by stream. The ferror function returns nonzero if and only if the error indicator is set for stream.

from the C99 Draft: http://www.vmunix.com/~gabor/c/draft.html. Any actual error codes used are, for the most part, implementation defined.

However, the GNU C library on linux also conforms to POSIX specifications:

http://pubs.opengroup.org/onlinepubs/9699919799/toc.htm

Which are much more well defined in this context. For example, if you look at the page for fopen:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html

You'll see a lot of detailed information, including specific errno codes, under Errors.

Again, the GNU C library used on virtually all normal linux systems is POSIX compliant, so you can count on that information ;). Those (online) POSIX man pages are also generally more detailed than the standard linux system man pages (read both).

WRT to file operations on other (non-POSIX) platforms, they will have their own implementations. Unfortunately, stuff like that is not transparently portable in standard C. C++ streams do have more standardized error handling, though.

Orwin answered 20/5, 2012 at 9:18 Comment(3)
Thanks. The POSIX definitions are very helpful. For example, accordng to them, "fgets" does indeed set errno. I think the best strategy for my particular case is to just write for POSIX and then fix Windows problems as they come up.Sennight
Although GNU's fopen() sets errno, fread() doesn't, even if POSIX specifies so (with a "CX" tag). Any ideas why?Rosa
The POSIX man page, at least, does not mention this. I notice the linux man page, though, doesn't mention errno at all.Orwin
J
3

According to the C11 standard, chapter 7.21 ("stdio.h"), only fgetpos, fsetpos and ftell write to errno in the event of an error.

Jailbird answered 20/5, 2012 at 11:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.