master xplshn/aruu / cmd / posix / kill.c
  1/* See LICENSE file for copyright and license details. */
  2
  3#include "sig.h"
  4#include "util.h"
  5
  6#include <sys/wait.h>
  7
  8#include <ctype.h>
  9#include <limits.h>
 10#include <signal.h>
 11#include <stdio.h>
 12#include <string.h>
 13#include <strings.h>
 14
 15static const char *
 16sig2name(int sig)
 17{
 18  static char name[SIG2STR_MAX];
 19
 20  if (sig == 0)
 21    return "0";
 22  if (sig2str(sig, name) < 0)
 23    eprintf("%d: bad signal number\n", sig);
 24  return name;
 25}
 26
 27static int
 28name2sig(const char *name)
 29{
 30  int sig;
 31
 32  if (strcmp(name, "0") == 0)
 33    return 0;
 34  if (str2sig(name, &sig) < 0)
 35    eprintf("%s: bad signal name\n", name);
 36  return sig;
 37}
 38
 39static void
 40usage(void)
 41{
 42  eprintf(
 43      "usage: %s [-s signame | -num | -signame] pid ...\n"
 44      "       %s -l [num]\n",
 45      argv0,
 46      argv0
 47  );
 48}
 49
 50// ?man kill: send signal to process
 51// ?man arguments: pid ...
 52// ?man send a specified signal to processes by pid
 53int
 54main(int argc, char *argv[])
 55{
 56  pid_t  pid;
 57  size_t i;
 58  int    ret = 0, sig = SIGTERM;
 59
 60  argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
 61
 62  if (!argc)
 63    usage();
 64
 65  if ((*argv)[0] == '-') {
 66    switch ((*argv)[1]) {
 67      case 'l':
 68        if ((*argv)[2])
 69          goto longopt;
 70        argc--, argv++;
 71        if (!argc) {
 72          for (i = 1; i < (size_t)sys_nsig; i++)
 73            if (sys_signame[i])
 74              puts(sys_signame[i]);
 75        } else if (argc == 1) {
 76          sig = estrtonum(*argv, 0, INT_MAX);
 77          if (sig > 128)
 78            sig = WTERMSIG(sig);
 79          puts(sig2name(sig));
 80        } else {
 81          usage();
 82        }
 83        return fshut(stdout, "<stdout>");
 84      case 's':
 85        if ((*argv)[2])
 86          goto longopt;
 87        argc--, argv++;
 88        if (!argc)
 89          usage();
 90        sig = name2sig(*argv);
 91        argc--, argv++;
 92        break;
 93      case '-':
 94        if ((*argv)[2])
 95          goto longopt;
 96        argc--, argv++;
 97        break;
 98      default:
 99      longopt:
100        /* XSI-extensions -argnum and -argname*/
101        if (isdigit((*argv)[1])) {
102          sig = estrtonum((*argv) + 1, 0, INT_MAX);
103          sig2name(sig);
104        } else {
105          sig = name2sig((*argv) + 1);
106        }
107        argc--, argv++;
108    }
109  }
110
111  if (argc && !strcmp(*argv, "--"))
112    argc--, argv++;
113
114  if (!argc)
115    usage();
116
117  for (; *argv; argc--, argv++) {
118    pid = estrtonum(*argv, INT_MIN, INT_MAX);
119    if (kill(pid, sig) < 0) {
120      weprintf("kill %d:", pid);
121      ret = 1;
122    }
123  }
124
125  return ret;
126}