Skip to content

fs: clear the end-of-file indicator before every read - #519

Open
The1TrueJoe wants to merge 1 commit into
ucode-lang:masterfrom
The1TrueJoe:fs-read-clear-eof
Open

The1TrueJoe wants to merge 1 commit into
ucode-lang:masterfrom
The1TrueJoe:fs-read-clear-eof

Conversation

@The1TrueJoe

Copy link
Copy Markdown

d075095 ("fs: keep the bytes a short read already delivered") clears the stream's indicators after read(<length>), but read("line"), read("all") and read(<delimiter>) still leave the end-of-file indicator set once they reach the end. stdio keeps it set (musl, glibc since 2.28, the BSDs), so every later read of those kinds on the handle returns nothing, even after more data has arrived: a file that grew, a tty in non-canonical mode with VMIN 0, a FIFO that got a new writer.

let r = fs.open('/tmp/f', 'r'), w = fs.open('/tmp/f', 'a');
r.read('line');            // "first\n"
r.read('line');            // null, at the end of the file
w.write('second\n');
w.flush();
r.read('line');            // null, where "second\n" is expected

This clears the indicators on entry to uc_fs_read_common(), so no read starts from a state an earlier one left behind. tests/custom/99_bugs/65_fs_read_sticky_eof covers all four modes; it fails without the change and passes with it.

Related: #514 handles an interrupted read("all") and clears the indicators in that branch. The two touch nearby lines but apply cleanly in either order.

Commit d075095 ("fs: keep the bytes a short read already delivered")
clears the stream's indicators after read(<length>), but read("line"),
read("all") and read(<delimiter>) still leave the end-of-file indicator
set once they reach the end. stdio keeps it set (musl, glibc since 2.28,
the BSDs), so every later read of those kinds on the handle returns
nothing, even after more data has arrived: a file that grew, a tty in
non-canonical mode with VMIN 0, a FIFO that got a new writer.

  let r = fs.open('/tmp/f', 'r'), w = fs.open('/tmp/f', 'a');
  r.read('line');            // "first\n"
  r.read('line');            // null, at the end of the file
  w.write('second\n');
  w.flush();
  r.read('line');            // null, where "second\n" is expected

Clear the indicators on entry, so that no read starts from a state an
earlier one left behind.

Signed-off-by: Joseph Telaak <joseph@telaak.dev>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant