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   18090 use warnings; no warnings 'redefine';
  12     12   28  
  12     2   385  
  12     2   62  
  12         28  
  12         340  
  2         16  
  2         4  
  2         56  
  2         10  
  2         5  
  2         56  
4 12     12   61 use rlib '../../../..';
  12     2   31  
  12         66  
  2         9  
  2         4  
  2         12  
5              
6             # FIXME: Complete doesn't work if in package.
7 12     12   4031 use Devel::Trepan::Complete;
  12     2   31  
  12         1301  
  2         611  
  2         4  
  2         170  
8             package Devel::Trepan::CmdProcessor::Command::Kill;
9              
10 12     12   650 use if !@ISA, Devel::Trepan::CmdProcessor::Command ;
  12     2   38  
  12         107  
  2         11  
  2         5  
  2         57  
11              
12 12     12   1983 use vars qw(@ISA);
  12     2   35  
  12         717  
  2         84  
  2         5  
  2         108  
13              
14             unless (@ISA) {
15 12     12   83 eval <<'EOE';
  12     12   27  
  12     12   698  
  12     12   71  
  12     12   29  
  12         503  
  12         64  
  12         30  
  12         481  
  12         70  
  12         27  
  12         548  
  12         69  
  12         34  
  12         460  
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   70 use strict;
  12     2   28  
  12         395  
  2         12  
  2         4  
  2         65  
24              
25             @ISA = @CMD_ISA;
26 12     12   61 use vars @CMD_VARS; # Value inherited from parent
  12     2   27  
  12         7032  
  2         11  
  2         3  
  2         1182  
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 2     2 0 1058 my ($self, $prefix) = @_;
  0     0 0    
70 2         11 my @matches = Devel::Trepan::Complete::signal_complete($prefix);
  0            
71 2 100       9 push @matches, 'unconditionally' if 0 == index('unconditionally', $prefix);
  0 0          
72 2         8 sort @matches;
  0            
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;