commit 7e2221112d5bf55860b4448755aab5d9a69590f7
Author: sin <[email protected]>
Date:   Tue Nov 11 14:40:47 2014 +0000

    Make kill(1) almost POSIX conformant
    
    Things not handled:
    
    * XSI extensions support is missing, -signal_name and -signal_number.
    * We cannot kill job IDs.

diff --git a/kill.1 b/kill.1
index 237ecfb..8801530 100644
--- a/kill.1
+++ b/kill.1
@@ -4,25 +4,26 @@ KILL \- signal processes
 .SH SYNOPSIS
 .B kill
 .RB [ \-s
-.IR signal ]
-.RI [ pid ...]
+.IR signal_name ]
+.IR pid
+.IR ...
 .P
 .B kill
 .B -l
-.RI [ signum ]
+.RI [ exit_status ]
 .SH DESCRIPTION
 .B kill
-sends a
+by default sends a
 .I TERM
 signal to the given processes.
 .SH OPTIONS
 .TP
-.BI \-s " signal"
-sends the named signal.
+.BI \-s " signal_name"
+Sends the named signal.
 .TP
 .B \-l
-lists available signals.  If a
-.I signum
+Lists available signals.  If an
+.I exit_status
 is given, only the corresponding signal name will be printed.
 .SH SEE ALSO
 .IR kill (2),
diff --git a/kill.c b/kill.c
index 59ef221..f66c84d 100644
--- a/kill.c
+++ b/kill.c
@@ -1,11 +1,13 @@
 /* See LICENSE file for copyright and license details. */
+#include <sys/wait.h>
+#include <errno.h>
 #include <signal.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <strings.h>
 #include <unistd.h>
-#include <sys/wait.h>
 #include "util.h"
 
 struct {
@@ -19,60 +21,110 @@ struct {
 #undef SIG
 };
 
+const char *sig2name(int);
+
 static void
 usage(void)
 {
-       eprintf("usage: %s [-s signal] [pid...]\n"
-               "       %s -l [signum]\n", argv0, argv0);
+       weprintf("usage: %s -s signal_name pid...\n", argv0);
+       weprintf("       %s -l [exit_status]\n", argv0);
+       exit(1);
 }
 
 int
 main(int argc, char *argv[])
 {
-       bool lflag = false;
-       char *end, *v;
+       char *end;
+       const char *name;
+       int ret = 0;
        int sig = SIGTERM;
        pid_t pid;
        size_t i;
 
-       ARGBEGIN {
-       case 'l':
-               lflag = true;
-               break;
-       case 's':
-               v = EARGF(usage());
-               sig = strtol(v, &end, 0);
-               if(*end == '\0')
-                       break;
-               for(i = 0; i < LEN(sigs); i++) {
-                       if(!strcasecmp(v, sigs[i].name)) {
-                               sig = sigs[i].sig;
-                               break;
+       argv0 = argv[0];
+       if (argc < 2)
+               usage();
+
+       argc--;
+       argv++;
+       if (strcmp(argv[0], "-l") == 0) {
+               argc--;
+               argv++;
+               if (argc == 0) {
+                       for (i = 0; i < LEN(sigs); i++)
+                               puts(sigs[i].name);
+                       exit(0);
+               }
+               for (; argc; argc--, argv++) {
+                       errno = 0;
+                       sig = strtol(argv[0], &end, 0);
+                       if (*end == '\0' && errno == 0) {
+                               name = sig2name(sig);
+                               if (!name)
+                                       printf("%d\n", sig);
+                               else
+                                       puts(name);
+                       } else {
+                               weprintf("%s: bad signal number\n", argv[0]);
+                               ret = 1;
                        }
                }
-               if(i == LEN(sigs))
-                       eprintf("%s: unknown signal\n", v);
-               break;
-       default:
-               usage();
-       } ARGEND;
+               exit(0);
+       } else if (strcmp(argv[0], "-s") == 0) {
+               argc--;
+               argv++;
+               if (argc == 0)
+                       usage();
+               if (strcmp(argv[0], "0") == 0) {
+                       sig = 0;
+               } else {
+                       for (i = 0; i < LEN(sigs); i++) {
+                               if (strcasecmp(sigs[i].name, argv[0]) == 0) {
+                                       sig = sigs[i].sig;
+                                       break;
+                               }
+                       }
+                       if (i == LEN(sigs))
+                               eprintf("%s: bad signal number\n", argv[0]);
+               }
+               argc--;
+               argv++;
+       } else if (strcmp(argv[0], "--") == 0) {
+               argc--;
+               argv++;
+               if (argc == 0)
+                       usage();
+       }
 
-       if(argc < 1 && !lflag)
+       if (argc == 0)
                usage();
 
-       if(lflag) {
-               sig = (argc > 0) ? estrtol(argv[0], 0) : 0;
-               if(sig > 128)
-                       sig = WTERMSIG(sig);
-               for(i = 0; i < LEN(sigs); i++)
-                       if(sigs[i].sig == sig || sig == 0)
-                               putword(sigs[i].name);
-               putchar('\n');
-       } else for(; argc > 0; argc--, argv++) {
-               pid = estrtol(argv[0], 0);
-               if(kill(pid, sig) == -1)
-                       eprintf("kill %d:", pid);
+       for (; argc; argc--, argv++) {
+               errno = 0;
+               pid = strtol(argv[0], &end, 0);
+               if (*end == '\0' && errno == 0) {
+                       if (kill(pid, sig) < 0) {
+                               weprintf("kill %d:", pid);
+                               ret = 1;
+                       }
+               } else {
+                       weprintf("%s: bad pid\n", argv[0]);
+                       ret = 1;
+               }
        }
 
-       return 0;
+       exit(ret);
+}
+
+const char *
+sig2name(int sig)
+{
+       size_t i;
+
+       if (sig > 128)
+               sig = WTERMSIG(sig);
+       for (i = 0; i < LEN(sigs); i++)
+               if (sigs[i].sig == sig)
+                       return sigs[i].name;
+       return NULL;
 }


Reply via email to