1#!./perl -w 2 3use strict; 4use Test::More; 5use Config; 6 7plan(skip_all => "POSIX is unavailable") 8 unless $Config{extensions} =~ /\bPOSIX\b/; 9plan(skip_all => "sigemptyset is unavailable on $^O") 10 if $^O eq 'MSWin32'; 11 12require POSIX; 13POSIX->import(); 14 15my @signo; 16my ($min, $max) = (~0, -1); 17 18sub expected_signals { 19 my $sigset = shift; 20 my $desc = shift; 21 my %expected; 22 ++$expected{$_} foreach @_; 23 24 local $Test::Builder::Level = $Test::Builder::Level + 1; 25 26 for my $sig ($min..$max) { 27 if ($expected{$sig}) { 28 cmp_ok($sigset->ismember($sig), '==', 1, 29 "$desc - sig $sig is a member"); 30 } else { 31 cmp_ok($sigset->ismember($sig), '==', 0, 32 "$desc - sig $sig is not a member"); 33 } 34 } 35} 36 37foreach (@POSIX::EXPORT) { 38 next unless /^SIG[A-Z0-9]+$/; 39 my $val = eval "POSIX::$_"; 40 next unless defined $val; 41 $min = $val if $min > $val; 42 $max = $val if $max < $val; 43 push @signo, $val; 44} 45 46# Sanity check that we found something: 47cmp_ok(scalar @signo, '>=', 6, 48 'found at least 6 signals (6 are named in the ANSI C spec)'); 49 50my $sigset = POSIX::SigSet->new(); 51isa_ok($sigset, 'POSIX::SigSet', 'checking the type of the object'); 52expected_signals($sigset, 'new object'); 53 54is($sigset->fillset(), '0 but true', 'fillset'); 55# because on some systems, not all integers are valid signals... 56# so the only thing we can really be confident about is that all the signals 57# with names are going to be present: 58foreach (@signo) { 59 cmp_ok($sigset->ismember($_), '==', 1, "after fillset sig $_ is a member"); 60} 61is($sigset->emptyset(), '0 but true', 'empyset'); 62expected_signals($sigset, 'after emptyset'); 63 64is($sigset->addset($signo[1]), '0 but true', 'addset'); 65expected_signals($sigset, 'after addset', $signo[1]); 66is($sigset->addset($signo[2]), '0 but true', 'addset'); 67expected_signals($sigset, 'after addset', $signo[1], $signo[2]); 68is($sigset->addset($signo[4]), '0 but true', 'addset'); 69expected_signals($sigset, 'after addset', $signo[1], $signo[2], $signo[4]); 70is($sigset->addset($signo[2]), '0 but true', 'addset'); 71expected_signals($sigset, 'after addset', $signo[1], $signo[2], $signo[4]); 72is($sigset->delset($signo[4]), '0 but true', 'delset'); 73expected_signals($sigset, 'after addset', $signo[1], $signo[2]); 74is($sigset->addset($signo[0]), '0 but true', 'addset'); 75expected_signals($sigset, 'after addset', $signo[0], $signo[1], $signo[2]); 76is($sigset->delset($signo[4]), '0 but true', 'delset'); 77expected_signals($sigset, 'after delset', $signo[0], $signo[1], $signo[2]); 78is($sigset->delset($signo[1]), '0 but true', 'delset'); 79expected_signals($sigset, 'after delset', $signo[0], $signo[2]); 80is($sigset->delset($signo[0]), '0 but true', 'delset'); 81expected_signals($sigset, 'after addset', $signo[2]); 82is($sigset->delset($signo[2]), '0 but true', 'delset'); 83expected_signals($sigset, 'empty again'); 84 85foreach ([$signo[0]], 86 [$signo[2]], 87 [$signo[3]], 88 [@signo[2,3,6]], 89 ) { 90 $sigset = POSIX::SigSet->new(@$_); 91 isa_ok($sigset, 'POSIX::SigSet', 'checking the type of the object'); 92 local $" = ', '; 93 expected_signals($sigset, "new(@$_)", @$_); 94} 95 96SKIP: 97{ 98 # CID 244386 99 # linux and freebsd do validate for positive and very large signal numbers 100 # darwin uses a macro that simply ignores large signals and shifts by 101 # a negative number for negative signals, always succeeding 102 # 103 # since the idea is to validate our code rather than the implementation 104 # of sigaddset, just test the platforms we know can fail 105 skip "Not all systems validate the signal number", 2 106 unless $^O =~ /^(linux|freebsd)$/; 107 my $badsig = -1; 108 note "badsig $badsig"; 109 ok(!eval{ POSIX::SigSet->new($badsig); 1 }, 110 "POSIX::SigSet->new should throw on large signal number"); 111 like($@."", qr/POSIX::Sigset->new: failed to add signal $badsig/, 112 "check message"); 113} 114 115done_testing(); 116