-
Notifications
You must be signed in to change notification settings - Fork 577
readline: clear the error flag if the error happens to be EAGAIN #22907
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: blead
Are you sure you want to change the base?
Conversation
@tonycoz Thank you for this! Looks like there's a rebase needed to get this merged. |
(or the equivalent EWOULDBLOCK) This allows questionable code that tries to combine select and the readline flavour of buffered I/O to limp along. Such code is still risky due to select() checking the underlying OS handle and not the perl handle. Fixes Perl#22883
fc24855
to
6f0b2f1
Compare
This would mean that suddenly readline returning |
@book, @ap , @haarg I request the guidance of the PSC. In response to #20060, in #20103 I changed the error handling for readline(), this was applied for perl 5.38 and was documented in perl5380delta. Previously it would clear the error flag on the stream on pretty much any error, so if there was any sort of error reading from the stream the error flag for the stream would simply be cleared. This was changed to clear the error state in much more limited cases. This can include errors like trying to read from an output handle, reading from a handle opened to a directory and EWOULDBLOCK errors on sockets marked as non-blocking. This could also include hard errors like EIO Note that readline() was the only read op that cleared the error state like this, using read() or getc() instead does not clear the stream error state. This has caused some breakage downstream, including each of the soft error cases above (#22883 #20376 #21240) In this particular PR after some discussion in #22883 I suggested only ignoring the non-blocking file handle errors, and this PR implements that, though mixing buffered I/O and select() is generally a mistake. So what I'm looking for here is: should readline() revert to clearing the error state? (and inconsistency with read(), getc()) If not, should the change here be applied, clearing the error state only on EWOULDBLOCK/EAGAIN? |
We talked this through at the in-person PSC meeting at the PTS today.
No. That would just resurrect #20060. Fixing that by removing the error-clearing from the end of readline was correct. The previous situation was already conceptually wrong, but that was much less obvious before we addressed #20060. Namely, the conceptual problem is that, in code which does a whole sequence of I/O operations without checking for errors, and then does an I/O operation after which it does check for errors, that error check can run into an error from any of the preceding I/O operations, even though it’s (99.999% of the time anyway) written to check for errors of only the last operation. So what we think should be done about #22883 in conjunction with #20060 is that every I/O operation needs to be preceded by clearing the error state. Then readline won’t need to do anything special about Does that sound right? Are we missing anything @tonycoz? |
If I understand what you're suggesting, if the user does:
In particular, if this happened for a |
So, actually, The issue remains for everyone not checking the return value of a |
For history, making the success of close depend on the error state was done just post 5.8.0, though I don't see anything in the 5.8.1 or 5.10.0 perldeltas. It was originally proposed in #7637 (transferred from RT) and applied as part of a batch of patches originally made to debian. From the original post the intent appears to be to ensure that write failures were preserved, so I don't think a general "clear errors every I/O" is the solution. e199e3b - the patch to make close fail if the error flag is set I spent some time looking through this and noticed in PerlIOUnix_read():
which prevents setting the error flag if the error was EAGAIN. This was a fix for #6062 This was added in ba85f2e but only modified PerlIOUnix_read() (and didn't include a test), not the higher layers, if I look at PerlIOBuf_fill():
which doesn't exclude EAGAIN errors from setting the stream error flag. So what if we change that:
All tests successful, what happens on a EAGAIN read?
So readline still returns the error, the error flag isn't set and it matches the apparent intent of ba85f2e. Still needs tests of some sort. Neither this change nor this PR fixes #23026 |
(or the equivalent EWOULDBLOCK)
This allows questionable code that tries to combine select and the
readline flavour of buffered I/O to limp along. Such code is still
risky due to select() checking the underlying OS handle and not
the perl handle.
Fixes #22883