Skip to content

stdio: fail-fast after _FILE_FLAG_ERROR, and a clearerr() to reset it #149

Description

@mgrossmann

Design note recorded from the #147 item 3 (SYNAD) work — deliberately NOT part of that fix, which keeps the API unchanged.

Once the SYNAD fix lands, an uncorrectable I/O error sets _FILE_FLAG_ERROR + errno=EIO and the stream keeps accepting write attempts: each subsequent __fputc()/__fflush() drives the same error path again, non-fatally, and fails again. That is the minimal-change behaviour and it is safe — but it is not what C callers expect, and it burns an I/O round trip per doomed write.

The idea to evaluate:

  • Fail fast: __fputc()/__fputs()/__fwrite() (and the read side: __fgetc()/__fread()) return EOF/0 immediately when _FILE_FLAG_ERROR is set, without touching the DCB again. C-standard-ish semantics: a stream in error state stays failed until explicitly cleared.
  • clearerr(FILE *): does not exist in libc370 today (feof()/ferror() are macros over fp->flags). Fail-fast without a way to clear the flag would make the state terminal; the two belong together. Also worth checking: rewind() traditionally clears the error indicator too.

Caveats to think through before building it:

  • _FILE_FLAG_ERROR is also set by older paths (e.g. __reopen() failure) — auditing every setter comes first, so fail-fast does not turn a previously recoverable state into a dead stream.
  • Consumers: ftpd/httpd/ufsd log through these streams; a fail-fast stream that silently drops log lines after one transient error may be worse operationally than retrying. That trade-off is the real decision, and it belongs to this issue, not to the SYNAD fix.

Refs: #147 (item 3), #145.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions