Skip to content

Commit

Permalink
t/io/eintr.t: Skip some tests on pre-16 Darwin.
Browse files Browse the repository at this point in the history
The tests where we write a string larger than the pipe size to
a pipe hang on 15.6.0, while they seem to work on Darwin 17.7.0.
So we will skip these tests on Darwin, if the major version is
less than 16. (We may adjust this is we have more reports on
which versions between 15.6.0 and 17.7.0 success/fail).

Note that the tests hang even if we send a string of 512 characters,
which is much, much smaller than the actual size of the string in
the test.
  • Loading branch information
Abigail committed Dec 15, 2018
1 parent 72b2b1d commit db55b51
Showing 1 changed file with 62 additions and 55 deletions.
117 changes: 62 additions & 55 deletions t/io/eintr.t
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ if ($^O eq 'VMS' || $^O eq 'MSWin32' || $^O eq 'cygwin' || $^O =~ /freebsd/ || $
exit 0;
}



my ($in, $out, $st, $sigst, $buf);

plan(tests => 10);
Expand Down Expand Up @@ -96,60 +98,65 @@ alarm(0);
ok(!$st, 'read/die: read status');
ok(close($in), 'read/die: close status');

# This used to be 1_000_000, but on Linux/ppc64 (POWER7) this kept
# consistently failing. At exactly 0x100000 it started passing
# again. Now we're asking the kernel what the pipe buffer is, and if
# that fails, hoping this number is bigger than any pipe buffer.
my $surely_this_arbitrary_number_is_fine = (eval {
use Fcntl qw(F_GETPIPE_SZ);
fcntl($out, F_GETPIPE_SZ, 0);
} || 0xfffff) + 1;

# close during print

fresh_io;
$SIG{ALRM} = sub { $sigst = close($out) ? "ok" : "nok" };
$buf = "a" x $surely_this_arbitrary_number_is_fine . "\n";
select $out; $| = 1; select STDOUT;
alarm(1);
$st = print $out $buf;
alarm(0);
is($sigst, 'nok', 'print/close: sig handler close status');
ok(!$st, 'print/close: print status');
ok(!close($out), 'print/close: close status');

# die during print

fresh_io;
$SIG{ALRM} = sub { die };
$buf = "a" x $surely_this_arbitrary_number_is_fine . "\n";
select $out; $| = 1; select STDOUT;
alarm(1);
$st = eval { print $out $buf };
alarm(0);
ok(!$st, 'print/die: print status');
# the close will hang since there's data to flush, so use alarm
alarm(1);
ok(!eval {close($out)}, 'print/die: close status');
alarm(0);

# close during close

# Apparently there's nothing in standard Linux that can cause an
# EINTR in close(2); but run the code below just in case it does on some
# platform, just to see if it segfaults.
fresh_io;
$SIG{ALRM} = sub { $sigst = close($in) ? "ok" : "nok" };
alarm(1);
close $in;
alarm(0);

# die during close

fresh_io;
$SIG{ALRM} = sub { die };
alarm(1);
eval { close $in };
alarm(0);
SKIP: {
skip "Tests hang on older versions of Darwin", 5
if $^O eq 'darwin' && $osmajmin < 16;

# This used to be 1_000_000, but on Linux/ppc64 (POWER7) this kept
# consistently failing. At exactly 0x100000 it started passing
# again. Now we're asking the kernel what the pipe buffer is, and if
# that fails, hoping this number is bigger than any pipe buffer.
my $surely_this_arbitrary_number_is_fine = (eval {
use Fcntl qw(F_GETPIPE_SZ);
fcntl($out, F_GETPIPE_SZ, 0);
} || 0xfffff) + 1;

# close during print

fresh_io;
$SIG{ALRM} = sub { $sigst = close($out) ? "ok" : "nok" };
$buf = "a" x $surely_this_arbitrary_number_is_fine . "\n";
select $out; $| = 1; select STDOUT;
alarm(1);
$st = print $out $buf;
alarm(0);
is($sigst, 'nok', 'print/close: sig handler close status');
ok(!$st, 'print/close: print status');
ok(!close($out), 'print/close: close status');

# die during print

fresh_io;
$SIG{ALRM} = sub { die };
$buf = "a" x $surely_this_arbitrary_number_is_fine . "\n";
select $out; $| = 1; select STDOUT;
alarm(1);
$st = eval { print $out $buf };
alarm(0);
ok(!$st, 'print/die: print status');
# the close will hang since there's data to flush, so use alarm
alarm(1);
ok(!eval {close($out)}, 'print/die: close status');
alarm(0);

# close during close

# Apparently there's nothing in standard Linux that can cause an
# EINTR in close(2); but run the code below just in case it does on some
# platform, just to see if it segfaults.
fresh_io;
$SIG{ALRM} = sub { $sigst = close($in) ? "ok" : "nok" };
alarm(1);
close $in;
alarm(0);

# die during close

fresh_io;
$SIG{ALRM} = sub { die };
alarm(1);
eval { close $in };
alarm(0);
}

# vim: ts=4 sts=4 sw=4:

0 comments on commit db55b51

Please sign in to comment.