Skip to content

Commit 44851a8

Browse files
committed
PerlIO: don't set the error flag when reading on an EAGAIN
This allows questionable code that tries to combine select and 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
1 parent a1af91d commit 44851a8

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

perlio.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4466,8 +4466,7 @@ PerlIOBuf_fill(pTHX_ PerlIO *f)
44664466
if (avail <= 0) {
44674467
if (avail == 0)
44684468
PerlIOBase(f)->flags |= PERLIO_F_EOF;
4469-
else
4470-
{
4469+
else if (errno != EAGAIN) {
44714470
PerlIOBase(f)->flags |= PERLIO_F_ERROR;
44724471
PerlIO_save_errno(f);
44734472
}

t/io/perlio.t

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ BEGIN {
66
skip_all_without_perlio();
77
}
88

9-
plan tests => 48;
9+
plan tests => 56;
1010

1111
use_ok('PerlIO');
1212

@@ -246,6 +246,41 @@ EOP
246246
ok !$main::PerlIO_code_injection, "Can't inject code via PerlIO->import";
247247
}
248248

249+
SKIP:
250+
{
251+
skip_without_dynamic_extension("IO", 8);
252+
253+
skip("Win32 can't make a pipe non-blocking", 8)
254+
if $^O eq "MSWin32";
255+
256+
$Config{d_pipe}
257+
or skip("No pipe", 8);
258+
259+
require IO::Select;
260+
261+
my ($in, $out);
262+
pipe($in, $out)
263+
or skip("Cannot pipe: $!", 8);
264+
265+
$in->blocking(0)
266+
or skip("Cannot make pipe non-blocking", 8);
267+
268+
my $line = <$in>;
269+
is($line, undef, "error reading (readline)");
270+
ok(!$in->error, "but did not set error flag (readline)");
271+
{
272+
local $::TODO = "read() uses the error flag to detect errors";
273+
is(read($in, my $buf, 10), undef, "error reading (read)");
274+
}
275+
ok(!$in->error, "but did not set error flag (read)");
276+
close $out;
277+
$line = <$in>;
278+
is($line, undef, "nothing to read, but eof");
279+
ok(!$in->error, "still did not set error flag");
280+
ok($in->eof, "did set eof");
281+
ok(close($in), "close success");
282+
}
283+
249284
END {
250285
unlink_all $txt;
251286
unlink_all $bin;

0 commit comments

Comments
 (0)