1898184e3Ssthen#!perl -w 2898184e3Ssthen 3898184e3Ssthen# We assume that TestInit has been used. 4898184e3Ssthen 5898184e3SsthenBEGIN { 6*b8851fccSafresh1 chdir 't' if -d 't'; 7898184e3Ssthen require './test.pl'; 8898184e3Ssthen} 9898184e3Ssthen 10898184e3Ssthenuse strict; 11898184e3Ssthenuse Config; 12898184e3Ssthen 1391f110e0Safresh1plan tests => 29; 1491f110e0Safresh1$| = 1; 15898184e3Ssthen 166fb12b70Safresh1watchdog(25); 17898184e3Ssthen 18898184e3Ssthen$SIG{ALRM} = sub { 19898184e3Ssthen die "Alarm!\n"; 20898184e3Ssthen}; 21898184e3Ssthen 22898184e3Ssthenpass('before the first loop'); 23898184e3Ssthen 24898184e3Ssthenalarm 2; 25898184e3Ssthen 26898184e3Sstheneval { 27898184e3Ssthen 1 while 1; 28898184e3Ssthen}; 29898184e3Ssthen 30898184e3Ssthenis($@, "Alarm!\n", 'after the first loop'); 31898184e3Ssthen 32898184e3Ssthenpass('before the second loop'); 33898184e3Ssthen 34898184e3Ssthenalarm 2; 35898184e3Ssthen 36898184e3Sstheneval { 37898184e3Ssthen while (1) { 38898184e3Ssthen } 39898184e3Ssthen}; 40898184e3Ssthen 41898184e3Ssthenis($@, "Alarm!\n", 'after the second loop'); 42898184e3Ssthen 43898184e3SsthenSKIP: { 44898184e3Ssthen skip('We can\'t test blocking without sigprocmask', 17) 45898184e3Ssthen if is_miniperl() || !$Config{d_sigprocmask}; 466fb12b70Safresh1 skip("This doesn\'t work on $^O threaded builds RT#88814", 17) 47*b8851fccSafresh1 if ($^O =~ /cygwin/ && $Config{useithreads}); 48*b8851fccSafresh1 skip("This doesn\'t work on $^O version $Config{osvers} RT#88814", 17) 49*b8851fccSafresh1 if ($^O eq "openbsd" && $Config{osvers} < 5.2); 50898184e3Ssthen 51898184e3Ssthen require POSIX; 52898184e3Ssthen my $pending = POSIX::SigSet->new(); 53898184e3Ssthen is POSIX::sigpending($pending), '0 but true', 'sigpending'; 54898184e3Ssthen is $pending->ismember(&POSIX::SIGUSR1), 0, 'SIGUSR1 is not pending'; 55898184e3Ssthen my $new = POSIX::SigSet->new(&POSIX::SIGUSR1); 56898184e3Ssthen POSIX::sigprocmask(&POSIX::SIG_BLOCK, $new); 57898184e3Ssthen 58898184e3Ssthen my $gotit = 0; 59898184e3Ssthen $SIG{USR1} = sub { $gotit++ }; 60898184e3Ssthen kill 'SIGUSR1', $$; 61898184e3Ssthen is $gotit, 0, 'Haven\'t received third signal yet'; 62898184e3Ssthen 63898184e3Ssthen diag "2nd sigpending crashes on cygwin" if $^O eq 'cygwin'; 64898184e3Ssthen is POSIX::sigpending($pending), '0 but true', 'sigpending'; 65898184e3Ssthen is $pending->ismember(&POSIX::SIGUSR1), 1, 'SIGUSR1 is pending'; 66898184e3Ssthen 67898184e3Ssthen my $old = POSIX::SigSet->new(); 68898184e3Ssthen POSIX::sigsuspend($old); 69898184e3Ssthen is $gotit, 1, 'Received third signal'; 70898184e3Ssthen is POSIX::sigpending($pending), '0 but true', 'sigpending'; 71898184e3Ssthen is $pending->ismember(&POSIX::SIGUSR1), 0, 'SIGUSR1 is no longer pending'; 72898184e3Ssthen 73898184e3Ssthen { 74898184e3Ssthen kill 'SIGUSR1', $$; 75898184e3Ssthen local $SIG{USR1} = sub { die "FAIL\n" }; 76898184e3Ssthen POSIX::sigprocmask(&POSIX::SIG_BLOCK, undef, $old); 77898184e3Ssthen ok $old->ismember(&POSIX::SIGUSR1), 'SIGUSR1 is blocked'; 78898184e3Ssthen eval { POSIX::sigsuspend(POSIX::SigSet->new) }; 79898184e3Ssthen is $@, "FAIL\n", 'Exception is thrown, so received fourth signal'; 80898184e3Ssthen POSIX::sigprocmask(&POSIX::SIG_BLOCK, undef, $old); 81898184e3SsthenTODO: 82898184e3Ssthen { 83898184e3Ssthen local $::TODO = "Needs investigation" if $^O eq 'VMS'; 84898184e3Ssthen ok $old->ismember(&POSIX::SIGUSR1), 'SIGUSR1 is still blocked'; 85898184e3Ssthen } 86898184e3Ssthen } 87898184e3Ssthen 88898184e3Ssthen POSIX::sigprocmask(&POSIX::SIG_BLOCK, $new); 89898184e3Ssthen kill 'SIGUSR1', $$; 90898184e3Ssthen is $gotit, 1, 'Haven\'t received fifth signal yet'; 91898184e3Ssthen POSIX::sigprocmask(&POSIX::SIG_UNBLOCK, $new, $old); 92898184e3Ssthen ok $old->ismember(&POSIX::SIGUSR1), 'SIGUSR1 was still blocked'; 93898184e3Ssthen is $gotit, 2, 'Received fifth signal'; 94898184e3Ssthen 95898184e3Ssthen # test unsafe signal handlers in combination with exceptions 96898184e3Ssthen 97898184e3Ssthen SKIP: { 98898184e3Ssthen # #89718: on old linux kernels, this test hangs. No-ones thought 99898184e3Ssthen # of a reliable way to probe for this, so for now, just skip the 100898184e3Ssthen # tests on production releases 101898184e3Ssthen skip("some OSes hang here", 3) if (int($]*1000) & 1) == 0; 102898184e3Ssthen 1036fb12b70Safresh1 SKIP: { 1046fb12b70Safresh1 skip("Issues on Android", 3) if $^O =~ /android/; 105898184e3Ssthen my $action = POSIX::SigAction->new(sub { $gotit--, die }, POSIX::SigSet->new, 0); 106898184e3Ssthen POSIX::sigaction(&POSIX::SIGALRM, $action); 107898184e3Ssthen eval { 108898184e3Ssthen alarm 1; 109898184e3Ssthen my $set = POSIX::SigSet->new; 110898184e3Ssthen POSIX::sigprocmask(&POSIX::SIG_BLOCK, undef, $set); 111898184e3Ssthen is $set->ismember(&POSIX::SIGALRM), 0, "SIGALRM is not blocked on attempt $_"; 112898184e3Ssthen POSIX::sigsuspend($set); 113898184e3Ssthen } for 1..2; 114898184e3Ssthen is $gotit, 0, 'Received both signals'; 115898184e3Ssthen } 116898184e3Ssthen} 1176fb12b70Safresh1} 118898184e3Ssthen 119898184e3SsthenSKIP: { 120898184e3Ssthen skip("alarm cannot interrupt blocking system calls on $^O", 2) 121898184e3Ssthen if $^O =~ /MSWin32|cygwin|VMS/; 122898184e3Ssthen # RT #88774 123898184e3Ssthen # make sure the signal handler's called in an eval block *before* 124898184e3Ssthen # the eval is popped 125898184e3Ssthen 126898184e3Ssthen $SIG{'ALRM'} = sub { die "HANDLER CALLED\n" }; 127898184e3Ssthen 128898184e3Ssthen eval { 129898184e3Ssthen alarm(2); 130898184e3Ssthen select(undef,undef,undef,10); 131898184e3Ssthen }; 132898184e3Ssthen alarm(0); 133898184e3Ssthen is($@, "HANDLER CALLED\n", 'block eval'); 134898184e3Ssthen 135898184e3Ssthen eval q{ 136898184e3Ssthen alarm(2); 137898184e3Ssthen select(undef,undef,undef,10); 138898184e3Ssthen }; 139898184e3Ssthen alarm(0); 140898184e3Ssthen is($@, "HANDLER CALLED\n", 'string eval'); 141898184e3Ssthen} 142898184e3Ssthen 143898184e3Sstheneval { $SIG{"__WARN__\0"} = sub { 1 } }; 144898184e3Ssthenlike $@, qr/No such hook: __WARN__\\0 at/, q!Fetching %SIG hooks with an extra trailing nul is nul-clean!; 145898184e3Ssthen 146898184e3Sstheneval { $SIG{"__DIE__\0whoops"} = sub { 1 } }; 147898184e3Ssthenlike $@, qr/No such hook: __DIE__\\0whoops at/; 148898184e3Ssthen 149898184e3Ssthen{ 150898184e3Ssthen use warnings; 151898184e3Ssthen my $w; 152898184e3Ssthen local $SIG{__WARN__} = sub { $w = shift }; 153898184e3Ssthen 154898184e3Ssthen $SIG{"KILL\0"} = sub { 1 }; 155898184e3Ssthen like $w, qr/No such signal: SIGKILL\\0 at/, 'Arbitrary signal lookup through %SIG is clean'; 156898184e3Ssthen} 15791f110e0Safresh1 15891f110e0Safresh1# [perl #45173] 15991f110e0Safresh1{ 16091f110e0Safresh1 my $int_called; 16191f110e0Safresh1 local $SIG{INT} = sub { $int_called = 1; }; 16291f110e0Safresh1 $@ = "died"; 16391f110e0Safresh1 is($@, "died"); 16491f110e0Safresh1 kill 'INT', $$; 16591f110e0Safresh1 # this is needed to ensure signal delivery on MSWin32 16691f110e0Safresh1 sleep(1); 16791f110e0Safresh1 is($int_called, 1); 16891f110e0Safresh1 is($@, "died"); 16991f110e0Safresh1} 170