What are the particular cases `getchar()` returns error?

Viewed 284

So i know getchar() returns EOF when input ended or an error occurred. I also know that i can check which of this cases occurred by ferror(stdin) and feof(stdin). I want to know what are the cases when error can occur in particular.

I checked man pages of both functions but there is nothing about it there.

2 Answers

All of stdio.h points at something called error indicator, which is an internal variable supposedly located in an opaque FILE object that the application programmer has no access to (see C17 7.21.1).

The documentation for getchar is found in C17 7.21.7.6:

The getchar function returns the next character from the input stream pointed to by stdin. If the stream is at end-of-file, the end-of-file indicator for the stream is set and getchar returns EOF. If a read error occurs, the error indicator for the stream is set and getchar returns EOF.

So we don't know if getchar returned EOF because it reached the end of the stream, or because there was a read error. In order to know, we'd have to check the error indicator.

This is where ferror(stdin) comes in. It's a mildly useful function, because it only does this (C17 7.21.10.3):

The ferror function returns nonzero if and only if the error indicator is set for stream.

And that's all there is to it - this is a standardized, portable abstraction layer and we can't really know what's going on underneath the hood. Which is nice, because most of the time we simply don't care.

There will be an OS-specific API underneath these standard C functions, in case of POSIX likely read(), in case of Windows likely ReadFile() etc. These functions in turn can fail for a number of reasons: incorrect file handles, file is taken by another process, no read access to the file given to the user by the OS and so on.

In theory getchar could as well be hooked up to a serial bus on an embedded system, in which case the reasons of it failing would be entirely different ones than on a hosted system. Now we are suddenly talking about wrong baudrate, buffer overruns, framing errors or whatever applies.

getchar() can return EOF for multiple system specific I/O errors. getchar() is defined to be equivalent to getc(stdin), itself equivalent to fgetc(stdin) except for the fact that it may be implemented as a macro. Here is a list of possible causes for linux systems from the linux man page:

RETURN VALUE

Upon successful completion, fgetc() shall return the next byte from the input stream pointed to by stream. If the end-of-file indicator for the stream is set, or if the stream is at end-of- file, the end-of-file indicator for the stream shall be set and fgetc() shall return EOF. If a read error occurs, the error indicator for the stream shall be set, fgetc() shall return EOF, and shall set errno to indicate the error.

ERRORS

The fgetc() function shall fail if data needs to be read and:

EAGAIN The O_NONBLOCK flag is set for the file descriptor underlying stream and the thread would be delayed in the fgetc() operation.

EBADF The file descriptor underlying stream is not a valid file descriptor open for reading.

EINTR The read operation was terminated due to the receipt of a signal, and no data was transferred.

EIO A physical I/O error has occurred, or the process is in a background process group attempting to read from its controlling terminal, and either the calling thread is blocking SIGTTIN or the process is ignoring SIGTTIN or the process group of the process is orphaned. This error may also be generated for implementation-defined reasons.

EOVERFLOW The file is a regular file and an attempt was made to read at or beyond the offset maximum associated with the corresponding stream.

The fgetc() function may fail if:

ENOMEM Insufficient storage space is available.

ENXIO A request was made of a nonexistent device, or the request was outside the capabilities of the device.

Related