#!/usr/bin/perl -w # # An implementation of the 'killpg' utility in Perl. # Borrowed from the Perl Power Tools (PPT) project. # Original by by Theo Van Dinter (felicity@kluge.net). # # kill,v 1.2 2004/08/05 14:17:43 cwest Exp # use strict; use Config; use integer; use File::Basename; my $myname = basename($0); $myname =~ s/\.\w*$//; # strip any extension # die if no signals or no arguments die "$myname: No signals defined ?!?" unless defined $Config{"sig_name"}; die "$myname: Too few arguments; try $0 -h\n" unless (@ARGV); my (@signals) = split(/\s+/, $Config{"sig_name"}); my ($signal) = 15; # default of SIGTERM my %hsignals; for (my ($i) = 1 ; $i <= $#signals ; $i++) { $hsignals{$signals[$i]} = $i; } if ($ARGV[0] =~ /^-l$/i) { # list signals for (my ($i) = 1 ; $i <= $#signals ; $i++) { printf "%2d:%-6s%s", $i, $signals[$i], (($i % 8 == 0) || ($i == $#signals)) ? "\n" : " "; } exit 0; } elsif ($ARGV[0] =~ /^-h$/i) { # help me! print "usage: $0 [-s signame] PID ... $0 [-signame] PID ... $0 [-signumber] PID ... $0 PID ... $0 [-hlvw] "; exit 0; } elsif ($ARGV[0] =~ /^-v$/i) { # version my $VERSION = sprintf("%d.%02d", q$Revision: 1.5 $ =~ /(\d+)\.(\d+)/); my $DATE = sprintf("%s", q$Date: 2009/07/28 16:44:44 $ =~ /Date: (.*) /); print "$myname $VERSION $DATE\n"; exit(0); } elsif ($ARGV[0] =~ /^-w$/i) { # where's the code my $SOURCE = sprintf("%s", print "$SOURCE\n"; exit(0); } elsif ($ARGV[0] =~ /^-\d+$/) { # -signalnumber ($signal) = ($ARGV[0] =~ /^-(\d+)/); die "$0: Bad signal number.\n" if ($signal > $#signals); shift @ARGV; } elsif ($ARGV[0] =~ /^-/) { # -NAME or -s NAME ($signal) = ($ARGV[0] =~ /^-(.+)$/); shift @ARGV; $signal = shift @ARGV if (lc $signal eq "s"); # -s has signalname param. $signal = uc $signal; $signal =~ s/^SIG//; # remove the "SIG" from SIGNAME die "$0: $signal: Unknown signal; $0 -l lists signals.\n" unless ($hsignals{$signal}); $signal = $hsignals{$signal}; } die "$myname: No PIDs specified.\n" unless (@ARGV); my ($ret) = 0; foreach (@ARGV) { # do the kills... unless (kill(-$signal, $_)) { warn "$myname: $_: $!\n"; $ret = 1; } } exit $ret; =head1 NAME killpg - send signals to a process group =head1 SYNOPSIS B [B<-s> I] PID ... B [B<-signame>] PID ... B [B<-signumber>] PID ... B [B<-hlvw>] =head1 DESCRIPTION B sends a signal to all process groups specified on the command line. This is typically done to cause one or more processes to terminate, reload configuration files, etc. Process groups can be very useful, especially for things like long-running scripts that spawn multiple programs. For example, this program creates compressed cpio-style files for backup: USER PID PPID PGID STIME TIME COMMAND root 9353 1 9352 17:29:12 00:00 /bin/ksh /root/bin/docopy root 18347 9353 9352 21:22:30 01:07 compress root 18346 9353 9352 21:22:30 00:09 pax -wd -x cpio If you wanted to stop this cleanly without relying on signals propagating from the parent process, you could kill all three PIDs, or just kill the process group-leader (9352). =head1 OPTIONS AND ARGUMENTS =over 4 =item I<-s> This parameter takes a single argument of a signal name (see -l) to be sent to the process groups. =item I<-signame> A short form of the C<-s signame> parameter. =item I<-signumber> This parameter specifies that the given signal number should be sent to the process groups. =item I<-h> Help. =item I<-l> Display a listing of all available signals on the current system. =item I<-v> Print the version and exit. =item I<-w> Print where the RCS sourcefile is and exit. =back =head1 NOTES If no signal is specified on the command line, SIGTERM is sent to the process groups. killpg returns 0 on success or >0 if an error occurred. Only the super-user may send signals to other users' processes. Signal names may have the I prefix, i.e. C and C are equivalent. The signal list C displays in an "extended" form which lists both the signal name and number for easy reference. =head1 HISTORY Original version rewritten for the Perl Power Tools project from the description of the kill program in OpenBSD. =head1 ORIGINAL AUTHOR Theo Van Dinter (felicity@kluge.net) Hacked up to kill process groups by Karl Vogel (vogelke@pobox.com) =head1 SEE ALSO ps(1), killpg(2) =cut