home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / slackwar / a / util / util-lin.2 / util-lin / util-linux-2.2 / misc-utils / kill.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-22  |  6.8 KB  |  273 lines

  1. /*
  2.  * Copyright (c) 1988, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33. /*
  34.  *  oct 5 1994 -- almost entirely re-written to allow for process names.
  35.  *  modifications (c) salvatore valente <svalente@mit.edu>
  36.  *  may be used / modified / distributed under the same terms as the original.
  37.  */
  38.  
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <ctype.h>
  43. #include <unistd.h>
  44. #include <signal.h>
  45.  
  46. #ifdef __linux__
  47. /*
  48.  *  sys_signame -- an ordered list of signals.
  49.  *  lifted from /usr/include/linux/signal.h
  50.  *  this particular order is only correct for linux.
  51.  *  this is _not_ portable.
  52.  */
  53. char *sys_signame[NSIG] = {
  54.     "zero",  "HUP",  "INT",   "QUIT", "ILL",   "TRAP", "IOT",  "UNUSED",
  55.     "FPE",   "KILL", "USR1",  "SEGV", "USR2",  "PIPE", "ALRM", "TERM",
  56.     "STKFLT","CHLD", "CONT",  "STOP", "TSTP",  "TTIN", "TTOU", "IO",
  57.     "XCPU",  "XFSZ", "VTALRM","PROF", "WINCH", NULL
  58. };
  59. #endif
  60.  
  61. int main (int argc, char *argv[]);
  62. char *mybasename(char *pathname);
  63. int signame_to_signum (char *sig);
  64. int arg_to_signum (char *arg);
  65. void nosig (char *name);
  66. void printsig (int sig);
  67. void printsignals (FILE *fp);
  68. int usage (int status);
  69. int kill_verbose (char *procname, int pid, int sig);
  70.  
  71. extern int *get_pids (char *, int);
  72.  
  73. char version_string[] = "kill v2.0\n";
  74. char *whoami;
  75.  
  76. int main (int argc, char *argv[])
  77. {
  78.     int errors, numsig, pid;
  79.     char *ep, *arg;
  80.     int do_pid, do_kill, check_all;
  81.     int *pids, *ip;
  82.  
  83.     whoami = mybasename (*argv);
  84.     numsig = SIGTERM;
  85.     do_pid = (! strcmp (whoami, "pid"));
  86.     do_kill = 0;
  87.     check_all = 0;
  88.  
  89.     /*  loop through the arguments.
  90.     actually, -a is the only option can be used with other options.
  91.     `kill' is basically a one-option-at-most program.  */
  92.     for (argc--, argv++; argc > 0; argc--, argv++) {
  93.     arg = *argv;
  94.     if (*arg != '-') {
  95.         break;
  96.     }
  97.     if (! strcmp (arg, "-u")) {
  98.         return usage (0);
  99.     }
  100.     if (! strcmp (arg, "-v")) {
  101.         fputs (version_string, stdout);
  102.         return 0;
  103.     }
  104.     if (! strcmp (arg, "-a")) {
  105.         check_all++;
  106.         continue;
  107.     }
  108.     if (! strcmp (arg, "-l")) {
  109.         if (argc < 2) {
  110.         printsignals (stdout);
  111.         return 0;
  112.         }
  113.         if (argc > 2) {
  114.         return usage (1);
  115.         }
  116.         /* argc == 2 */
  117.         arg = argv[1];
  118.         if ((numsig = arg_to_signum (arg)) < 0) {
  119.         fprintf (stderr, "%s: unknown signal %s\n", whoami, arg);
  120.         return 1;
  121.         }
  122.         printsig (numsig);
  123.         return 0;
  124.     }
  125.     if (! strcmp (arg, "-p")) {
  126.         do_pid++;
  127.         if (do_kill)
  128.         return usage (1);
  129.         continue;
  130.     }
  131.     if (! strcmp (arg, "-s")) {
  132.         if (argc < 2) {
  133.         return usage (1);
  134.         }
  135.         do_kill++;
  136.         if (do_pid)
  137.         return usage (1);
  138.         argc--, argv++;
  139.         arg = *argv;
  140.         if ((numsig = arg_to_signum (arg)) < 0) {
  141.         nosig (arg);
  142.         return 1;
  143.         }
  144.         continue;
  145.     }
  146.     /*  `arg' begins with a dash but is not a known option.
  147.         so it's probably something like -HUP.
  148.         try to deal with it.  */
  149.     arg++;
  150.     if ((numsig = arg_to_signum (arg)) < 0) {
  151.         return usage (1);
  152.     }
  153.     do_kill++;
  154.     if (do_pid)
  155.         return usage (1);
  156.     continue;
  157.     }
  158.  
  159.     if (! *argv) {
  160.     return usage (1);
  161.     }
  162.     if (do_pid) {
  163.     numsig = -1;
  164.     }
  165.  
  166.     /*  we're done with the options.
  167.     the rest of the arguments should be process ids and names.
  168.     kill them.  */
  169.     for (errors = 0; (arg = *argv) != NULL; argv++) {
  170.     pid = strtol (arg, &ep, 10);
  171.     if (! *ep)
  172.         errors += kill_verbose (arg, pid, numsig);
  173.     else {
  174.         pids = get_pids (arg, check_all);
  175.         if (! pids) {
  176.         errors++;
  177.         fprintf (stderr, "%s: can't find process \"%s\"\n",
  178.              whoami, arg);
  179.         continue;
  180.         }
  181.         for (ip = pids; *ip >= 0; ip++)
  182.         errors += kill_verbose (arg, *ip, numsig);
  183.         free (pids);
  184.     }
  185.     }
  186.     return (errors);
  187. }
  188.  
  189. char *mybasename (char *path)
  190. {
  191.     char *cp;
  192.  
  193.     cp = strrchr (path, '/');
  194.     return (cp ? cp + 1 : path);
  195. }
  196.  
  197. int signame_to_signum (char *sig)
  198. {
  199.     int n;
  200.  
  201.     if (! strncasecmp (sig, "sig", 3))
  202.     sig += 3;
  203.     for (n = 1; (n < NSIG) && (sys_signame[n] != NULL); n++) {
  204.     if (! strcasecmp (sys_signame[n], sig))
  205.         return n;
  206.     }
  207.     return (-1);
  208. }
  209.  
  210. int arg_to_signum (char *arg)
  211. {
  212.     int numsig;
  213.     char *ep;
  214.  
  215.     if (isdigit (*arg)) {
  216.     numsig = strtol (arg, &ep, 10);
  217.     if (*ep != 0 || numsig < 0 || numsig >= NSIG)
  218.         return (-1);
  219.     return (numsig);
  220.     }
  221.     return (signame_to_signum (arg));
  222. }
  223.  
  224. void nosig (char *name)
  225. {
  226.     fprintf (stderr, "%s: unknown signal %s; valid signals:\n", whoami, name);
  227.     printsignals (stderr);
  228. }
  229.  
  230. void printsig (int sig)
  231. {
  232.     printf ("%s\n", sys_signame[sig]);
  233. }
  234.  
  235. void printsignals (FILE *fp)
  236. {
  237.     int n;
  238.  
  239.     for (n = 1; (n < NSIG) && (sys_signame[n] != NULL); n++) {
  240.     fputs (sys_signame[n], fp);
  241.     if (n == (NSIG / 2) || n == (NSIG - 1))
  242.         fputc ('\n', fp);
  243.     else
  244.         fputc (' ', fp);
  245.     }
  246.     if (n < (NSIG - 1))
  247.     fputc ('\n', fp);
  248. }
  249.  
  250. int usage (int status)
  251. {
  252.     FILE *fp;
  253.  
  254.     fp = (status == 0 ? stdout : stderr);
  255.     fprintf (fp, "usage: %s [ -s signal | -p ] [ -a ] pid ...\n", whoami);
  256.     fprintf (fp, "       %s -l [ signal ]\n", whoami);
  257.     return status;
  258. }
  259.  
  260. int kill_verbose (char *procname, int pid, int sig)
  261. {
  262.     if (sig < 0) {
  263.     printf ("%d\n", pid);
  264.     return 0;
  265.     }
  266.     if (kill (pid, sig) < 0) {
  267.     fprintf (stderr, "%s ", whoami);
  268.     perror (procname);
  269.     return 1;
  270.     }
  271.     return 0;
  272. }
  273.