What is clearerr used for?

There is at least one real world use case for clearerr: when you want to mimic tail -f on a file that is not opened in exclusive mode. That means that another (or many other) process(es) write at the end of a file, and one process repeatedly reads even after having reached the end of file in order to look whether new data has arrived. In that case, could would look like:

for (;;) {
    if (NULL == fgets(line, sizeof(line), fd)) {
        sleep(n);
        clearerr(fd);     // reset EOF condition
    }
    else {
        fputs(line, fdout);
    }
}

Functions that set the error status of a FILE (as reported by ferror) do not clear it even if later called successfully. Likewise if you encounter the end of file while reading, it will not be cleared automatically even if the file later has more data available.

Basically this means that if you are using ferror to check for an error state and you have some way of recovering from it, the ferror will keep indicating an error until you use clearerr.

In your example, if you just use the return value of fread as the condition for terminating the read (i.e., EOF and any type of error are considered final), there is no need to clearerr: just fall through to fclose (and perhaps use ferror to determine whether to print an error message).

On the other hand, if the FILE is in fact a stream on which read can later succeed, and you detect (or assume) that specific condition and retry, you should clearerr before retrying or you will keep seeing the old error condition on future attempts.

Likewise, as pointed out in comments, clearerr also clears the end of file state, so this also applies when using feof to check for the end of file. (Note, however, that you generally shouldn't use !feof(file) as the loop condition when reading.)


clearerr() clears the error and EOF flags from a stream.

Say FILE were like this:

typedef struct {
    int fd;
    char *buf;
    int error;
    int eof;
} FILE;
FILE *file;

This would set file->error and file->eof to 0.

Some reasons for doing this include file I/O, such as when a file gives EOF, but then another program (or another thread, etc.) appends to it. If you clear the error after doing this, you can have your program act as sort of a tail -f-substitute.

Tags:

C