Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | package Psh::Builtins::Kill; |
2 | ||
3 | =item * C<kill [-SIGNAL] [%JOB | PID | JOBNAME] | -l> | |
4 | ||
5 | Send SIGNAL (which defaults to TERM) to the given process, specified | |
6 | either as a job (%NN) or as a pid (a number). | |
7 | ||
8 | =cut | |
9 | ||
10 | sub bi_kill | |
11 | { | |
12 | if( ! Psh::OS::has_job_control()) { | |
13 | Psh::Util::print_error_i18n('no_jobcontrol'); | |
14 | return (0,undef); | |
15 | } | |
16 | ||
17 | my @args = split(' ',$_[0]); | |
18 | my $sig= 'TERM'; | |
19 | my (@pids, $job); | |
20 | ||
21 | unless (@args) { | |
22 | require Psh::Builtins::Help; | |
23 | Psh::Builtins::Help::bi_help('kill'); | |
24 | return (0,undef); | |
25 | } | |
26 | ||
27 | ||
28 | if (scalar(@args) == 1 && | |
29 | $args[0] eq '-l') { | |
30 | require Config; | |
31 | Psh::Util::print_out($Config::Config{sig_name}."\n"); | |
32 | return (0,undef); | |
33 | } elsif( substr($args[0],0,1) eq '-') { | |
34 | $sig= substr($args[0],1); | |
35 | shift @args; | |
36 | } | |
37 | ||
38 | my $count= 0; | |
39 | foreach my $pid (@args) { | |
40 | if ($pid =~ m|^%(\d+)$|) { | |
41 | my $temp = $1 - 1; | |
42 | ||
43 | $job= Psh::Joblist::find_job($temp); | |
44 | if( !defined($job)) { | |
45 | Psh::Util::print_error_i18n('bi_kill_no_such_job',$pid); | |
46 | next; | |
47 | } | |
48 | ||
49 | $pid = $job->{pid}; | |
50 | } | |
51 | elsif ($pid !~ m/^\d+$/) { | |
52 | my ($index,$rpid)= Psh::Joblist::find_last_with_name($pid); | |
53 | if( $rpid) { | |
54 | $pid=$rpid; | |
55 | } else { | |
56 | Psh::Util::print_error_i18n('bi_kill_no_such_job',$pid); | |
57 | next; | |
58 | } | |
59 | } | |
60 | ||
61 | if ($sig ne 'CONT' and Psh::Joblist::job_exists($pid) | |
62 | and !(($job=Psh::Joblist::get_job($pid))->{running})) { | |
63 | #Better wake up the process so it can respond to this signal | |
64 | $job->continue; | |
65 | } | |
66 | ||
67 | $sig=0 if $sig eq 'ZERO'; # stupid perl bug | |
68 | ||
69 | if (my $num=CORE::kill($sig, $pid) != 1) { | |
70 | Psh::Util::print_error_i18n('bi_kill_error_sig',$pid,$sig); | |
71 | next; | |
72 | } else { | |
73 | $count+=$num; | |
74 | } | |
75 | ||
76 | if ($sig eq 'CONT' and Psh::Joblist::job_exists($pid)) { | |
77 | Psh::Joblist::get_job($pid)->{running}=1; | |
78 | } | |
79 | } | |
80 | return ($count!=0,$count); | |
81 | } | |
82 | ||
83 | # Completion function for kill | |
84 | sub cmpl_kill { | |
85 | my( $text, $pretext, $starttext) = @_; | |
86 | my @tmp= (); | |
87 | ||
88 | Psh::Joblist::enumerate(); | |
89 | while( my $job= Psh::Joblist::each()) { | |
90 | push @tmp, $job->{call}; | |
91 | } | |
92 | ||
93 | my @tmp2= split /\s+/, $starttext; # just to remove a deprecated message... | |
94 | if( @tmp2<2) { | |
95 | require Config; | |
96 | push @tmp, map { '-'.$_} split(' ', $Config::Config{sig_name}); | |
97 | } | |
98 | ||
99 | return (1,grep { Psh::Util::starts_with($_,$text) } | |
100 | @tmp); | |
101 | } | |
102 | ||
103 | 1; |