LCOV - code coverage report
Current view: top level - builtins - kill.def (source / functions) Hit Total Coverage
Test: cov-sh.info Lines: 33 94 35.1 %
Date: 2020-10-29 14:49:55 Functions: 1 2 50.0 %

          Line data    Source code
       1             : This file is kill.def, from which is created kill.c.
       2             : It implements the builtin "kill" in Bash.
       3             : 
       4             : Copyright (C) 1987-2015 Free Software Foundation, Inc.
       5             : 
       6             : This file is part of GNU Bash, the Bourne Again SHell.
       7             : 
       8             : Bash is free software: you can redistribute it and/or modify
       9             : it under the terms of the GNU General Public License as published by
      10             : the Free Software Foundation, either version 3 of the License, or
      11             : (at your option) any later version.
      12             : 
      13             : Bash is distributed in the hope that it will be useful,
      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             : GNU General Public License for more details.
      17             : 
      18             : You should have received a copy of the GNU General Public License
      19             : along with Bash.  If not, see <http://www.gnu.org/licenses/>.
      20             : 
      21             : $PRODUCES kill.c
      22             : 
      23             : $BUILTIN kill
      24             : $FUNCTION kill_builtin
      25             : $SHORT_DOC kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
      26             : Send a signal to a job.
      27             : 
      28             : Send the processes identified by PID or JOBSPEC the signal named by
      29             : SIGSPEC or SIGNUM.  If neither SIGSPEC nor SIGNUM is present, then
      30             : SIGTERM is assumed.
      31             : 
      32             : Options:
      33             :   -s sig        SIG is a signal name
      34             :   -n sig        SIG is a signal number
      35             :   -l    list the signal names; if arguments follow `-l' they are
      36             :                 assumed to be signal numbers for which names should be listed
      37             :   -L    synonym for -l
      38             : 
      39             : Kill is a shell builtin for two reasons: it allows job IDs to be used
      40             : instead of process IDs, and allows processes to be killed if the limit
      41             : on processes that you can create is reached.
      42             : 
      43             : Exit Status:
      44             : Returns success unless an invalid option is given or an error occurs.
      45             : $END
      46             : 
      47             : #include <config.h>
      48             : 
      49             : #include <stdio.h>
      50             : #include <errno.h>
      51             : #if defined (HAVE_UNISTD_H)
      52             : #  ifdef _MINIX
      53             : #    include <sys/types.h>
      54             : #  endif
      55             : #  include <unistd.h>
      56             : #endif
      57             : 
      58             : #include "../bashansi.h"
      59             : #include "../bashintl.h"
      60             : 
      61             : #include <signal.h>
      62             : 
      63             : #include "../shell.h"
      64             : #include "../trap.h"
      65             : #include "../jobs.h"
      66             : #include "common.h"
      67             : 
      68             : /* Not all systems declare ERRNO in errno.h... and some systems #define it! */
      69             : #if !defined (errno)
      70             : extern int errno;
      71             : #endif /* !errno */
      72             : 
      73             : extern int posixly_correct;
      74             : 
      75             : static void kill_error __P((pid_t, int));
      76             : 
      77             : #if !defined (CONTINUE_AFTER_KILL_ERROR)
      78             : #  define CONTINUE_OR_FAIL return (EXECUTION_FAILURE)
      79             : #else
      80             : #  define CONTINUE_OR_FAIL goto continue_killing
      81             : #endif /* CONTINUE_AFTER_KILL_ERROR */
      82             : 
      83             : /* Here is the kill builtin.  We only have it so that people can type
      84             :    kill -KILL %1?  No, if you fill up the process table this way you
      85             :    can still kill some. */
      86             : int
      87          75 : kill_builtin (list)
      88             :      WORD_LIST *list;
      89             : {
      90          75 :   int sig, any_succeeded, listing, saw_signal, dflags;
      91          75 :   char *sigspec, *word;
      92          75 :   pid_t pid;
      93          75 :   intmax_t pid_value;
      94             : 
      95          75 :   if (list == 0)
      96             :     {
      97          51 :       builtin_usage ();
      98          51 :       return (EX_USAGE);
      99             :     }
     100          24 :   CHECK_HELPOPT (list);
     101             : 
     102          24 :   any_succeeded = listing = saw_signal = 0;
     103          24 :   sig = SIGTERM;
     104          24 :   sigspec = "TERM";
     105             : 
     106          24 :   dflags = DSIG_NOCASE | ((posixly_correct == 0) ? DSIG_SIGPREFIX : 0);
     107             :   /* Process options. */
     108          24 :   while (list)
     109             :     {
     110          24 :       word = list->word->word;
     111             : 
     112          24 :       if (ISOPTION (word, 'l') || ISOPTION (word, 'L'))
     113             :         {
     114           0 :           listing++;
     115           0 :           list = list->next;
     116             :         }
     117          24 :       else if (ISOPTION (word, 's') || ISOPTION (word, 'n'))
     118             :         {
     119           0 :           list = list->next;
     120           0 :           if (list)
     121             :             {
     122           0 :               sigspec = list->word->word;
     123           0 :               if (sigspec[0] == '0' && sigspec[1] == '\0')
     124             :                 sig = 0;
     125             :               else
     126           0 :                 sig = decode_signal (sigspec, dflags);
     127           0 :               list = list->next;
     128           0 :               saw_signal++;
     129             :             }
     130             :           else
     131             :             {
     132           0 :               sh_needarg (word);
     133           0 :               return (EXECUTION_FAILURE);
     134             :             }
     135             :         }
     136          24 :       else if (ISOPTION (word, '-'))
     137             :         {
     138           0 :           list = list->next;
     139           0 :           break;
     140             :         }
     141          24 :       else if (ISOPTION (word, '?'))
     142             :         {
     143           0 :           builtin_usage ();
     144           0 :           return (EX_USAGE);
     145             :         }
     146             :       /* If this is a signal specification then process it.  We only process
     147             :          the first one seen; other arguments may signify process groups (e.g,
     148             :          -num == process group num). */
     149          24 :       else if (*word == '-' && saw_signal == 0)
     150             :         {
     151           0 :           sigspec = word + 1;
     152           0 :           sig = decode_signal (sigspec, dflags);
     153           0 :           saw_signal++;
     154           0 :           list = list->next;
     155             :         }
     156             :       else
     157             :         break;
     158             :     }
     159             : 
     160          24 :   if (listing)
     161           0 :     return (display_signal_list (list, 0));
     162             : 
     163             :   /* OK, we are killing processes. */
     164          24 :   if (sig == NO_SIG)
     165             :     {
     166           0 :       sh_invalidsig (sigspec);
     167           0 :       return (EXECUTION_FAILURE);
     168             :     }
     169             : 
     170          24 :   if (list == 0)
     171             :     {
     172           0 :       builtin_usage ();
     173           0 :       return (EX_USAGE);
     174             :     }
     175             : 
     176          60 :   while (list)
     177             :     {
     178          36 :       word = list->word->word;
     179             : 
     180          36 :       if (*word == '-')
     181           0 :         word++;
     182             : 
     183             :       /* Use the entire argument in case of minus sign presence. */
     184          36 :       if (*word && legal_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value))
     185             :         {
     186           0 :           pid = (pid_t) pid_value;
     187             : 
     188           0 :           if (kill_pid (pid, sig, pid < -1) < 0)
     189             :             {
     190           0 :               if (errno == EINVAL)
     191           0 :                 sh_invalidsig (sigspec);
     192             :               else
     193           0 :                 kill_error (pid, errno);
     194           0 :               CONTINUE_OR_FAIL;
     195             :             }
     196             :           else
     197           0 :             any_succeeded++;
     198             :         }
     199             : #if defined (JOB_CONTROL)
     200          36 :       else if (*list->word->word && *list->word->word != '%')
     201             :         {
     202          36 :           builtin_error (_("%s: arguments must be process or job IDs"), list->word->word);
     203          36 :           CONTINUE_OR_FAIL;
     204             :         }
     205           0 :       else if (*word)
     206             :         /* Posix.2 says you can kill without job control active (4.32.4) */
     207             :         {                       /* Must be a job spec.  Check it out. */
     208           0 :           int job;
     209           0 :           sigset_t set, oset;
     210           0 :           JOB *j;
     211             : 
     212           0 :           BLOCK_CHILD (set, oset);
     213           0 :           job = get_job_spec (list);
     214             : 
     215           0 :           if (INVALID_JOB (job))
     216             :             {
     217           0 :               if (job != DUP_JOB)
     218           0 :                 sh_badjob (list->word->word);
     219           0 :               UNBLOCK_CHILD (oset);
     220           0 :               CONTINUE_OR_FAIL;
     221             :             }
     222             : 
     223           0 :           j = get_job_by_jid (job);
     224             :           /* Job spec used.  Kill the process group. If the job was started
     225             :              without job control, then its pgrp == shell_pgrp, so we have
     226             :              to be careful.  We take the pid of the first job in the pipeline
     227             :              in that case. */
     228           0 :           pid = IS_JOBCONTROL (job) ? j->pgrp : j->pipe->pid;
     229             : 
     230           0 :           UNBLOCK_CHILD (oset);
     231             : 
     232           0 :           if (kill_pid (pid, sig, 1) < 0)
     233             :             {
     234           0 :               if (errno == EINVAL)
     235           0 :                 sh_invalidsig (sigspec);
     236             :               else
     237           0 :                 kill_error (pid, errno);
     238           0 :               CONTINUE_OR_FAIL;
     239             :             }
     240             :           else
     241           0 :             any_succeeded++;
     242             :         }
     243             : #endif /* !JOB_CONTROL */
     244             :       else
     245             :         {
     246           0 :           sh_badpid (list->word->word);
     247           0 :           CONTINUE_OR_FAIL;
     248             :         }
     249          36 :     continue_killing:
     250          36 :       list = list->next;
     251             :     }
     252             : 
     253          24 :   return (any_succeeded ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
     254             : }
     255             : 
     256             : static void
     257           0 : kill_error (pid, e)
     258             :      pid_t pid;
     259             :      int e;
     260             : {
     261           0 :   char *x;
     262             : 
     263           0 :   x = strerror (e);
     264           0 :   if (x == 0)
     265           0 :     x = _("Unknown error");
     266           0 :   builtin_error ("(%ld) - %s", (long)pid, x);
     267           0 : }

Generated by: LCOV version 1.14.0.6.4058