xref: /openbsd-src/gnu/usr.bin/perl/t/op/kill0.t (revision 5759b3d249badf144a6240f7eec4dcf9df003e6b)
1850e2753Smillert#!./perl
2850e2753Smillert
3850e2753SmillertBEGIN {
4850e2753Smillert    chdir 't' if -d 't';
5850e2753Smillert    require './test.pl';
6*5759b3d2Safresh1    set_up_inc('../lib');
7850e2753Smillert}
8850e2753Smillert
9850e2753SmillertBEGIN {
10850e2753Smillert    if ($^O eq 'riscos') {
11850e2753Smillert	skip_all("kill() not implemented on this platform");
12850e2753Smillert    }
13850e2753Smillert}
14850e2753Smillert
15850e2753Smillertuse strict;
166fb12b70Safresh1use Config;
17850e2753Smillert
186fb12b70Safresh1plan tests => 9;
19850e2753Smillert
20850e2753Smillertok( kill(0, $$), 'kill(0, $pid) returns true if $pid exists' );
21850e2753Smillert
22850e2753Smillert# It's not easy to come up with an individual PID that is known not to exist,
23850e2753Smillert# so just check that at least some PIDs in a large range are reported not to
24850e2753Smillert# exist.
25850e2753Smillertmy $count = 0;
26850e2753Smillertmy $total = 30_000;
27850e2753Smillertfor my $pid (1 .. $total) {
28850e2753Smillert  ++$count if kill(0, $pid);
29850e2753Smillert}
30850e2753Smillert# It is highly unlikely that all of the above PIDs are genuinely in use,
31850e2753Smillert# so $count should be less than $total.
32850e2753Smillertok( $count < $total, 'kill(0, $pid) returns false if $pid does not exist' );
33b39c5158Smillert
34b39c5158Smillert# Verify that trying to kill a non-numeric PID is fatal
35b39c5158Smillertmy @bad_pids = (
36b39c5158Smillert    [ undef , 'undef'         ],
37b39c5158Smillert    [ ''    , 'empty string'  ],
38b39c5158Smillert    [ 'abcd', 'alphabetic'    ],
39b39c5158Smillert);
40b39c5158Smillert
41b39c5158Smillertfor my $case ( @bad_pids ) {
42b39c5158Smillert  my ($pid, $name) = @$case;
43b39c5158Smillert  eval { kill 0, $pid };
44b39c5158Smillert  like( $@, qr/^Can't kill a non-numeric process ID/, "dies killing $name pid");
45b39c5158Smillert}
46b39c5158Smillert
47898184e3Ssthen# Verify that killing a magic variable containing a number doesn't
48898184e3Ssthen# trigger the above
49898184e3Ssthen{
50898184e3Ssthen  my $x = $$ . " ";
51898184e3Ssthen  $x =~ /(\d+)/;
52898184e3Ssthen  ok(eval { kill 0, $1 }, "can kill a number string in a magic variable");
53898184e3Ssthen}
546fb12b70Safresh1
556fb12b70Safresh1
566fb12b70Safresh1# RT #121230: test process group kill on Win32
576fb12b70Safresh1
586fb12b70Safresh1SKIP: {
596fb12b70Safresh1  skip 'custom process group kill() only on Win32', 3 if ($^O ne 'MSWin32');
606fb12b70Safresh1
616fb12b70Safresh1  # Create 2 child processes: an outer one created by kill0.t that runs
626fb12b70Safresh1  # the "op/kill0_child" script, and an inner one created by outer that
636fb12b70Safresh1  # just does 'sleep 5'. We then try to kill both of them as a single
646fb12b70Safresh1  # process group. If only the outer one is killed, the inner will stay
656fb12b70Safresh1  # around and eventually print "not ok 9999", presenting out of sequence
666fb12b70Safresh1  # TAP to harness. The outer child creates a temporary file when it is
676fb12b70Safresh1  # ready.
686fb12b70Safresh1
696fb12b70Safresh1  my $killfile = 'tmp-killchildstarted';
706fb12b70Safresh1  unlink($killfile);
716fb12b70Safresh1  die "can't unlink $killfile: $!" if -e $killfile;
726fb12b70Safresh1  eval q{END {unlink($killfile);}};
736fb12b70Safresh1
746fb12b70Safresh1  my $pid = system(1, $^X, 'op/kill0_child', $killfile);
756fb12b70Safresh1  die 'PID is 0' if !$pid;
766fb12b70Safresh1  while( ! -e $killfile) {
776fb12b70Safresh1    sleep 1; # a sleep 0 with $i++ would take ~160 iterations here
786fb12b70Safresh1  }
796fb12b70Safresh1  # (some ways to manually make this test fail:
806fb12b70Safresh1  #   change '-KILL' to 'KILL';
816fb12b70Safresh1  #   change $pid to a bogus number)
826fb12b70Safresh1  is(kill('-KILL', $pid), 1, 'process group kill, named signal');
836fb12b70Safresh1
846fb12b70Safresh1  # create a mapping of signal names to numbers
856fb12b70Safresh1
866fb12b70Safresh1  my ($i, %signo, @signame, $sig_name) = 0;
876fb12b70Safresh1  ($sig_name = $Config{sig_name}) || die "No signals?";
886fb12b70Safresh1  foreach my $name (split(' ', $sig_name)) {
896fb12b70Safresh1    $signo{$name} = $i;
906fb12b70Safresh1    $signame[$i] = $name;
916fb12b70Safresh1    $i++;
926fb12b70Safresh1  }
936fb12b70Safresh1  ok(scalar keys %signo > 1 && exists $signo{KILL},
946fb12b70Safresh1        '$Config{sig_name} parsed correctly');
956fb12b70Safresh1  die "a child proc wasn't killed and did cleanup on its own" if ! -e $killfile;
966fb12b70Safresh1  unlink $killfile;
976fb12b70Safresh1
986fb12b70Safresh1  # Now repeat the test with a numeric kill sigbal
996fb12b70Safresh1
1006fb12b70Safresh1  die "can't unlink" if -e $killfile;
1016fb12b70Safresh1  # no need to create another END block: already done earlier
1026fb12b70Safresh1  $pid = system(1, $^X, 'op/kill0_child', $killfile);
1036fb12b70Safresh1  die 'PID is 0' if !$pid;
1046fb12b70Safresh1  while( ! -e $killfile) {
1056fb12b70Safresh1    sleep 1; # a sleep 0 with $i++ would take ~160 iterations here
1066fb12b70Safresh1  }
1076fb12b70Safresh1  is(kill(-$signo{KILL}, $pid), 1, 'process group kill, numeric signal');
1086fb12b70Safresh1}
109