File Coverage

lib/Devel/Trepan/CmdProcessor/Command/Kill.pm
Criterion Covered Total %
statement 67 107 62.6
branch 2 28 7.1
condition 0 24 0.0
subroutine 22 25 88.0
pod 0 4 0.0
total 91 188 48.4


line stmt bran cond sub pod time code
1             # Copyright (C) 2011-2012, 2014 Rocky Bernstein <rocky@cpan.org>
2             # -*- coding: utf-8 -*-
3 12     12   72138 use warnings; no warnings 'redefine';
  12     12   41  
  12     2   387  
  12     2   63  
  12         73  
  12         349  
  2         20  
  2         5  
  2         59  
  2         10  
  2         6  
  2         59  
4 12     12   61 use rlib '../../../..';
  12     2   23  
  12         67  
  2         547  
  2         4  
  2         9  
5              
6             # FIXME: Complete doesn't work if in package.
7 12     12   4605 use Devel::Trepan::Complete;
  12     2   25  
  12         1410  
  2         732  
  2         4  
  2         200  
8             package Devel::Trepan::CmdProcessor::Command::Kill;
9              
10 12     12   759 use if !@ISA, Devel::Trepan::CmdProcessor::Command ;
  12     2   37  
  12         91  
  2         13  
  2         4  
  2         16  
11              
12 12     12   20208 use vars qw(@ISA);
  12     2   26  
  12         750  
  2         75  
  2         4  
  2         121  
13              
14             unless (@ISA) {
15 12     12   74 eval <<'EOE';
  12     12   30  
  12     12   669  
  12     12   74  
  12     12   27  
  12         875  
  12         90  
  12         25  
  12         567  
  12         73  
  12         26  
  12         649  
  12         120  
  12         33  
  12         458  
16             use constant ALIASES => ('kill!');
17             use constant CATEGORY => 'running';
18             use constant SHORT_HELP => 'Send this process a POSIX signal';
19             use constant MIN_ARGS => 0; # Need at least this many
20             use constant MAX_ARGS => 1; # Need at most this many - undef -> unlimited.
21             EOE
22             }
23 12     12   89 use strict;
  12     2   24  
  12         488  
  2         10  
  2         4  
  2         77  
24              
25             @ISA = @CMD_ISA;
26 12     12   69 use vars @CMD_VARS; # Value inherited from parent
  12     2   32  
  12         11621  
  2         10  
  2         4  
  2         1405  
27              
28             our $NAME = set_name();
29             =pod
30              
31             =head2 Synopsis:
32              
33             =cut
34             our $HELP = <<'HELP';
35             =pod
36              
37             B<kill>[B<!>] [I<signal-number>|I<signal-name>]
38              
39             Kill execution of program being debugged.
40              
41             Equivalent of C<kill('KILL', $$)>. This is an unmaskable
42             signal. Use this when all else fails, e.g. in thread code, use this.
43              
44             If you are in interactive mode, you are prompted to confirm killing.
45             However when this command is aliased from a command ending in C<!>, no
46             questions are asked.
47              
48             =head2 Examples:
49              
50             kill
51             kill KILL # same as above
52             kill kill # same as above
53             kill -9 # same as above
54             kill 9 # same as above
55             kill! 9 # same as above, but no questions asked
56             kill unconditionally # same as above
57             kill TERM # Send "TERM" signal
58              
59             =head2 See also:
60              
61             See also L<C<set
62             confirm>|Devel::Trepan::CmdProcessor::Command::Set::Confirm> and
63             L<C<quit>|Devel::Trepan::CmdProcessor::Command::Quit>.
64              
65             =cut
66             HELP
67              
68             sub complete($$) {
69 0     0 0 0 my ($self, $prefix) = @_;
  2     2 0 2622  
70 0         0 my @matches = Devel::Trepan::Complete::signal_complete($prefix);
  2         11  
71 0 0       0 push @matches, 'unconditionally' if 0 == index('unconditionally', $prefix);
  2 100       10  
72 0         0 sort @matches;
  2         8  
73             }
74              
75             # This method runs the command
76             sub run($$) {
77 0     0 0   my ($self, $args) = @_;
  0     0 0    
78 0           my $unconditional = substr($args->[0], -1, 1) eq '!';
  0            
79 0           my $sig;
  0            
80 0 0         if (scalar(@$args) > 1) {
  0 0          
81 0           $sig = uc($args->[1]);
  0            
82 0 0 0       unless ( ($sig =~ /[+-]?\d+/) || exists $SIG{$sig} ) {
  0 0 0        
83 0           $self->errmsg("Signal name '${sig}' is not a signal I know about.");
  0            
84 0           return;
  0            
85             }
86             } else {
87 0 0 0       if ($unconditional || $self->{proc}->confirm('Really quit?', 0)) {
  0 0 0        
88 0           $sig = 'KILL';
  0            
89             } else {
90 0           $self->msg('Kill not confirmed.');
  0            
91 0           return;
  0            
92             }
93             }
94 0 0         if (kill(0, $$)) {
  0 0          
95             # Force finalization on interface.
96 0 0 0       $self->{proc}{interfaces} = [] if
  0 0 0        
      0        
      0        
97             'KILL' eq $sig || 9 eq $sig || -9 eq $sig;
98 0 0         if (kill($sig, $$)) {
  0 0          
99 0           $self->msg("kill ${sig} successfully sent to process $$");
  0            
100             } else {
101 0           $self->errmsg("Kill ${sig} to process $$ not accepted: $!")
  0            
102             }
103             } else {
104 0           $self->errmsg(["Unable kill ${sig} to process $$",
  0            
105             "Different uid and not super-user?"]);
106             }
107             }
108              
109             unless (caller()) {
110             require Devel::Trepan::CmdProcessor;
111             my $proc = Devel::Trepan::CmdProcessor->new;
112             my $cmd = __PACKAGE__->new($proc);
113             print $cmd->{help}, "\n";
114             print join(', ', @{$cmd->{aliases}}), "\n";
115             print "min args: ", eval('$' . __PACKAGE__ . "::MIN_ARGS"), "\n";
116             for my $arg ('hu', 'HU', '', 1, '-9') {
117             printf "complete($arg) => %s\n", join(", ", $cmd->complete($arg));
118             }
119             for my $arg (qw(fooo 100 1 -1 HUP -9)) {
120             print "$NAME ${arg}\n";
121             $cmd->run([$NAME, $arg]);
122             my $sep = '=' x 40 . "\n";
123             print $sep;
124             }
125             }
126              
127             1;