-
Notifications
You must be signed in to change notification settings - Fork 560
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
close fails with irrelevant errors after perl 5.38 #22883
Comments
@jkeenan while |
This code does not attempt buffered I/O on a non-blocking handle.
Using readline in combination with select (aka IO::Select) is dangerous, if the remote process sends two lines that arrive as a single packet, readline will read the first line and leave the second line in the buffer but can_read() will not consider the handle readable until the next packet arrives, possibly deadlocking your process.
can_read() doesn't do anything that can produce
Unfortunately, not quite, they can have different numbers, and a read(2) that would block on a non-blocking socket is permitted to return either.
I do think clearing the error on an EAGAIN or EWOULDBLOCK is a reasonable workaround for historically questionable code. I think only those two errors should be suppressed, other errors should already be handled at a lower level (EINTR), are real issues (EISDIR, EIO, EINVAL) or indicate a serious bug (EFAULT, EBADF). It's possible non-POSIX platforms return other errors reasonable to preserve. Other functions like read() (perl's read not the system call), getc() do not do this error clearing that readline() historically did. |
(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
(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
After upgrade from perl 5.36 to 5.40, we began encountering issues with code that used Git::Repository. This module uses System::Command to interface with the git command line binary. We implemented a modified $git->run, which does the following:
This code is pretty much straight out of the documentation example in IO::Select.
During cleanup, System::Command does the following to its handles for
$stdin
/$stdout
/$stderr
and this is causing a lot of noise right now for us:It's not uncommon to see this on CPAN, and it's even worse: We see
close $fh or die...
, which means all of this code now unexpectedly blows up.Digging deeper into our problem, we determined that the
IO::Select
methodcan_read
is causingEAGAIN
(or is itEWOULDBLOCK
? They're the same error) to be put as an error on the file handle, which now causes close to exit non-zero.In the change introduced by #20103, which addressed issues raised by #20060, they were concerned with losing errors on the file handle during close. While I can see some value in EISDIR being retained, I struggle to understand why we would retain ALL of the errors, especially if there is a successful read afterwards.
I would prefer #20103 to be reverted, but I think we're past that, so I want to suggest an alternative to @tonycoz, who worked on this originally: Possibly, we could restore the
PerlIO_clearerr
unless the error set are specific ones we care about. In my specific case, I would argue that EAGAIN should be cleared if there is later a successful read, right?The text was updated successfully, but these errors were encountered: