This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #112990] Simplify kill implementation and docs
authorDarin McBride <dmcbride@cpan.org>
Tue, 26 Jun 2012 16:24:56 +0000 (09:24 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 26 Jun 2012 16:24:56 +0000 (09:24 -0700)
Clean up kill implementation and clear up the docs in perlfunc to be less
ambiguous and encompass more of its behaviour.

a)   kill -INT => $pid;

was surprisingly doing a "kill 0, $pid" instead of being the same as "kill -2,
$pid" (killing the process group for $pid with an interrupt).  Now negative
signal names will be allowed and be the same as if the name was replaced with
the signal number it represents.

b) remove all calls to killpg() as killpg is defined in terms of kill anyway.

c) Clarify the use of signal names vs numbers in perlfunc so that using names
is not so well hidden, as well as explaining the usage of negative signal
numbers as well as negative process IDs.

doio.c
pod/perlfunc.pod

diff --git a/doio.c b/doio.c
index f770fc1..6890d12 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -1579,6 +1579,7 @@ Perl_apply(pTHX_ I32 type, register SV **mark, register SV **sp)
     const char *s;
     STRLEN len;
     SV ** const oldmark = mark;
+    bool killgp = false;
 
     PERL_ARGS_ASSERT_APPLY;
 
@@ -1689,6 +1690,12 @@ nothing in the core.
        if (mark == sp)
            break;
        s = SvPVx_const(*++mark, len);
+       if (*s == '-' && isALPHA(s[1]))
+       {
+           s++;
+           len--;
+            killgp = true;
+       }
        if (isALPHA(*s)) {
            if (*s == 'S' && s[1] == 'I' && s[2] == 'G') {
                s += 3;
@@ -1698,12 +1705,18 @@ nothing in the core.
                Perl_croak(aTHX_ "Unrecognized signal name \"%"SVf"\"", SVfARG(*mark));
        }
        else
+       {
            val = SvIV(*mark);
+           if (val < 0)
+           {
+               killgp = true;
+                val = -val;
+           }
+       }
        APPLY_TAINT_PROPER();
        tot = sp - mark;
 #ifdef VMS
        /* kill() doesn't do process groups (job trees?) under VMS */
-       if (val < 0) val = -val;
        if (val == SIGKILL) {
            /* Use native sys$delprc() to insure that target process is
             * deleted; supervisor-mode images don't pay attention to
@@ -1736,34 +1749,19 @@ nothing in the core.
            break;
        }
 #endif
-       if (val < 0) {
-           val = -val;
-           while (++mark <= sp) {
-               I32 proc;
-               SvGETMAGIC(*mark);
-               if (!(SvIOK(*mark) || SvNOK(*mark) || looks_like_number(*mark)))
-                   Perl_croak(aTHX_ "Can't kill a non-numeric process ID");
-               proc = SvIV_nomg(*mark);
-               APPLY_TAINT_PROPER();
-#ifdef HAS_KILLPG
-               if (PerlProc_killpg(proc,val))  /* BSD */
-#else
-               if (PerlProc_kill(-proc,val))   /* SYSV */
-#endif
-                   tot--;
-           }
-       }
-       else {
-           while (++mark <= sp) {
-               I32 proc;
-               SvGETMAGIC(*mark);
-               if (!(SvIOK(*mark) || SvNOK(*mark) || looks_like_number(*mark)))
-                   Perl_croak(aTHX_ "Can't kill a non-numeric process ID");
-               proc = SvIV_nomg(*mark);
-               APPLY_TAINT_PROPER();
-               if (PerlProc_kill(proc, val))
-                   tot--;
+       while (++mark <= sp) {
+           I32 proc;
+           SvGETMAGIC(*mark);
+           if (!(SvIOK(*mark) || SvNOK(*mark) || looks_like_number(*mark)))
+               Perl_croak(aTHX_ "Can't kill a non-numeric process ID");
+           proc = SvIV_nomg(*mark);
+           if (killgp)
+           {
+                proc = -proc;
            }
+           APPLY_TAINT_PROPER();
+           if (PerlProc_kill(proc, val))
+               tot--;
        }
        PERL_ASYNC_CHECK();
        break;
index 766ec40..f409872 100644 (file)
@@ -3178,11 +3178,20 @@ L<perlport> for notes on the portability of this construct.
 Unlike in the shell, if SIGNAL is negative, it kills process groups instead
 of processes.  That means you usually
 want to use positive not negative signals.
-You may also use a signal name in quotes.
+
+You may also use a signal name in quotes.  A negative signal name is the
+same as a negative signal number, killing process groups instead of processes.
+For example, C<kill -KILL, $pgrp> will send C<SIGKILL> to the entire process
+group specified.
 
 The behavior of kill when a I<PROCESS> number is zero or negative depends on
 the operating system.  For example, on POSIX-conforming systems, zero will
-signal the current process group and -1 will signal all processes.
+signal the current process group, -1 will signal all processes, and any
+other negative PROCESS number will act as a negative signal number and
+kill the entire process group specified.
+
+If both the SIGNAL and the PROCESS are negative, the results are undefined.
+A warning may be produced in a future version.
 
 See L<perlipc/"Signals"> for more details.