]> granicus.if.org Git - procps-ng/commitdiff
kill: split out from skill/snice
authorCraig Small <csmall@enc.com.au>
Fri, 25 Sep 2015 23:13:13 +0000 (09:13 +1000)
committerCraig Small <csmall@enc.com.au>
Fri, 25 Sep 2015 23:13:13 +0000 (09:13 +1000)
The first part of fixing skill/snice to use the library instead
of directly readdir()ing /proc which is what it does now.

Remove the kill code from the skill/snice code and put common
elements into lib/signals.c Not 100% sure that is the right
destination instead of a new lib file, but ok for now.

kill shares some parsing logic with skill/snice but mainly
around signal specifications. The "do it" code is very different.

Signed-off-by: Craig Small <csmall@enc.com.au>
Makefile.am
include/signals.h
kill.c [new file with mode: 0644]
lib/signals.c
skill.c

index 1efa33270419f8fc5bd43b183fe8c95e0c78a722..e48f0aa4f79501ccfedb6298ad155cfb015d5fa0 100644 (file)
@@ -78,7 +78,7 @@ endif
 if BUILD_KILL
 bin_PROGRAMS += kill
 dist_man_MANS += kill.1
-kill_SOURCES = skill.c lib/strutils.c lib/fileutils.c lib/signals.c
+kill_SOURCES = kill.c lib/strutils.c lib/fileutils.c lib/signals.c
 else
   EXTRA_DIST += kill.1
 endif
index 474685faa49ba1ec0bf40b7c96956bda97a9af60..695b29971f735a7b23cd67f073f2dac8e717f0c1 100644 (file)
@@ -24,5 +24,13 @@ extern int signal_name_to_number(const char *__restrict name);
 
 extern const char *signal_number_to_name(int signo);
 
+extern int skill_sig_option(int *argc, char **argv);
+
+extern char *strtosig(const char *restrict s);
+
+extern void pretty_print_signals(void);
+
+extern void unix_print_signals(void);
+
 __END_DECLS
 #endif
diff --git a/kill.c b/kill.c
new file mode 100644 (file)
index 0000000..ce1e3c2
--- /dev/null
+++ b/kill.c
@@ -0,0 +1,139 @@
+/*
+ * kill.c - send a signal to process
+ * Copyright 1998-2002 by Albert Cahalan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <unistd.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+
+#include "c.h"
+#include "signals.h"
+#include "strutils.h"
+#include "nls.h"
+
+/* kill help */
+static void __attribute__ ((__noreturn__)) print_usage(FILE * out)
+{
+    fputs(USAGE_HEADER, out);
+    fprintf(out,
+              _(" %s [options] <pid> [...]\n"), program_invocation_short_name);
+    fputs(USAGE_OPTIONS, out);
+    fputs(_(" <pid> [...]            send signal to every <pid> listed\n"), out);
+    fputs(_(" -<signal>, -s, --signal <signal>\n"
+        "                        specify the <signal> to be sent\n"), out);
+    fputs(_(" -l, --list=[<signal>]  list all signal names, or convert one to a name\n"), out);
+    fputs(_(" -L, --table            list all signal names in a nice table\n"), out);
+    fputs(USAGE_SEPARATOR, out);
+    fputs(USAGE_HELP, out);
+    fputs(USAGE_VERSION, out);
+    fprintf(out, USAGE_MAN_TAIL("kill(1)"));
+    exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+int main(int argc, char **argv)
+{
+    int signo, i, sigopt=0, loop=1;
+    long pid;
+    int exitvalue = EXIT_SUCCESS;
+
+    static const struct option longopts[] = {
+        {"list", optional_argument, NULL, 'l'},
+        {"table", no_argument, NULL, 'L'},
+        {"signal", required_argument, NULL, 's'},
+        {"help", no_argument, NULL, 'h'},
+        {"version", no_argument, NULL, 'V'},
+        {NULL, 0, NULL, 0}
+    };
+
+
+    setlocale (LC_ALL, "");
+    bindtextdomain(PACKAGE, LOCALEDIR);
+    textdomain(PACKAGE);
+
+
+    if (argc < 2)
+        print_usage(stderr);
+
+    signo = skill_sig_option(&argc, argv);
+    if (signo < 0)
+        signo = SIGTERM;
+    else
+        sigopt++;
+
+    opterr=0; /* suppress errors on -123 */
+    while (loop == 1 && (i = getopt_long(argc, argv, "l::Ls:hV", longopts, NULL)) != -1)
+        switch (i) {
+        case 'l':
+            if (optarg) {
+                char *s;
+                s = strtosig(optarg);
+                if (s)
+                    printf("%s\n", s);
+                else
+                    xwarnx(_("unknown signal name %s"),
+                          optarg);
+                free(s);
+            } else {
+                unix_print_signals();
+            }
+            exit(EXIT_SUCCESS);
+        case 'L':
+            pretty_print_signals();
+            exit(EXIT_SUCCESS);
+        case 's':
+            signo = signal_name_to_number(optarg);
+            break;
+        case 'h':
+            print_usage(stdout);
+        case 'V':
+            fprintf(stdout, PROCPS_NG_VERSION);
+            exit(EXIT_SUCCESS);
+        case '?':
+            if (!isdigit(optopt)) {
+                xwarnx(_("invalid argument %c"), optopt);
+                print_usage(stderr);
+            } else {
+                /* Special case for signal digit negative
+                 * PIDs */
+                pid = (long)('0' - optopt);
+                if (kill((pid_t)pid, signo) != 0)
+                exitvalue = EXIT_FAILURE;
+                exit(exitvalue);
+            }
+            loop=0;
+            break;
+        default:
+            print_usage(stderr);
+        }
+
+    argc -= optind + sigopt;
+    argv += optind;
+
+    for (i = 0; i < argc; i++) {
+        pid = strtol_or_err(argv[i], _("failed to parse argument"));
+        if (!kill((pid_t) pid, signo))
+            continue;
+        exitvalue = EXIT_FAILURE;
+        continue;
+    }
+
+    return exitvalue;
+}
index 6b468d22bd6e75fda84145802b0c667d7a01a1c1..cff3966c8279232be93ded62e5bad0f0c5a0fb9d 100644 (file)
@@ -198,3 +198,96 @@ const char *signal_number_to_name(int signo)
     return buf;
 }
 
+int skill_sig_option(int *argc, char **argv)
+{
+    int i, nargs = *argc;
+    int signo = -1;
+    for (i = 1; i < nargs; i++) {
+        if (argv[i][0] == '-') {
+            signo = signal_name_to_number(argv[i] + 1);
+            if (-1 < signo) {
+                if (nargs - i) {
+                    nargs--;
+                    memmove(argv + i, argv + i + 1,
+                        sizeof(char *) * (nargs - i));
+                }
+                return signo;
+            }
+        }
+    }
+    return signo;
+}
+
+
+/* strtosig is similar to print_given_signals() with exception, that
+ * this function takes a string, and converts it to a signal name or
+ * a number string depending on which way a round conversion is
+ * queried.  Non-existing signals return NULL.  Notice that the
+ * returned string should be freed after use.
+ */
+char *strtosig(const char *restrict s)
+{
+    char *converted = NULL, *copy, *p, *endp;
+    int i, numsignal = 0;
+
+    copy = strdup(s);
+    if (!copy)
+        xerrx(EXIT_FAILURE, "cannot duplicate string");
+    for (p = copy; *p != '\0'; p++)
+        *p = toupper(*p);
+    p = copy;
+    if (p[0] == 'S' && p[1] == 'I' && p[2] == 'G')
+        p += 3;
+    if (isdigit(*p)){
+        numsignal = strtol(s,&endp,10);
+        if(*endp || endp==s)
+            return NULL; /* not valid */
+    }
+    if (numsignal){
+        for (i = 0; i < number_of_signals; i++){
+            if (numsignal == get_sigtable_num(i)){
+                converted = strdup(get_sigtable_name(i));
+                break;
+            }
+        }
+    } else {
+        for (i = 0; i < number_of_signals; i++){
+            if (strcmp(p, get_sigtable_name(i)) == 0){
+                converted = malloc(sizeof(char) * 8);
+                if (converted)
+                    snprintf(converted,
+                         sizeof(converted) - 1,
+                         "%d", get_sigtable_num(i));
+                break;
+            }
+        }
+    }
+    free(p);
+    return converted;
+}
+
+void unix_print_signals(void)
+{
+   int pos = 0;
+    int i = 0;
+    while(++i <= number_of_signals){
+        if(i-1) printf("%c", (pos>73)?(pos=0,'\n'):(pos++,' ') );
+        pos += printf("%s", signal_number_to_name(i));
+    }
+    printf("\n");
+}
+
+void pretty_print_signals(void)
+{
+    int i = 0;
+    while(++i <= number_of_signals){
+        int n;
+        n = printf("%2d %s", i, signal_number_to_name(i));
+        if(n>0 && i%7)
+            printf("%s", "           \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + n);
+        else
+            printf("\n");
+    }
+    if((i-1)%7) printf("\n");
+}
+
diff --git a/skill.c b/skill.c
index fcd5c54b3d099d5d71e34a8f2cb3b621f9143e4d..584e22ee28de89ec063ee7e1b3debddd7c7e7c65 100644 (file)
--- a/skill.c
+++ b/skill.c
@@ -76,17 +76,11 @@ static int sig_or_pri;
 
 enum {
     PROG_UNKNOWN,
-    PROG_KILL,
     PROG_SKILL,
     PROG_SNICE
 };
 static int program = PROG_UNKNOWN;
 
-static void display_kill_version(void)
-{
-    fprintf(stdout, PROCPS_NG_VERSION);
-}
-
 static int ns_flags = 0x3f;
 static int parse_namespaces(char *optarg)
 {
@@ -120,78 +114,6 @@ static int parse_namespaces(char *optarg)
     return 0;
 }
 
-static void unix_print_signals(void)
-{
-   int pos = 0;
-    int i = 0;
-    while(++i <= number_of_signals){
-        if(i-1) printf("%c", (pos>73)?(pos=0,'\n'):(pos++,' ') );
-        pos += printf("%s", signal_number_to_name(i));
-    }
-    printf("\n");
-}
-
-static void pretty_print_signals(void)
-{
-    int i = 0;
-    while(++i <= number_of_signals){
-        int n;
-        n = printf("%2d %s", i, signal_number_to_name(i));
-        if(n>0 && i%7)
-            printf("%s", "           \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + n);
-        else
-            printf("\n");
-    }
-    if((i-1)%7) printf("\n");
-}
-
-/* strtosig is similar to print_given_signals() with exception, that
- * this function takes a string, and converts it to a signal name or
- * a number string depending on which way a round conversion is
- * queried.  Non-existing signals return NULL.  Notice that the
- * returned string should be freed after use.
- */
-static char *strtosig(const char *restrict s)
-{
-    char *converted = NULL, *copy, *p, *endp;
-    int i, numsignal = 0;
-
-    copy = strdup(s);
-    if (!copy)
-        xerrx(EXIT_FAILURE, "cannot duplicate string");
-    for (p = copy; *p != '\0'; p++)
-        *p = toupper(*p);
-    p = copy;
-    if (p[0] == 'S' && p[1] == 'I' && p[2] == 'G')
-        p += 3;
-    if (isdigit(*p)){
-        numsignal = strtol(s,&endp,10);
-        if(*endp || endp==s)
-            return NULL; /* not valid */
-    }
-    if (numsignal){
-        for (i = 0; i < number_of_signals; i++){
-            if (numsignal == get_sigtable_num(i)){
-                converted = strdup(get_sigtable_name(i));
-                break;
-            }
-        }
-    } else {
-        for (i = 0; i < number_of_signals; i++){
-            if (strcmp(p, get_sigtable_name(i)) == 0){
-                converted = malloc(sizeof(char) * 8);
-                if (converted)
-                    snprintf(converted,
-                         sizeof(converted) - 1,
-                         "%d", get_sigtable_num(i));
-                break;
-            }
-        }
-    }
-    free(p);
-    return converted;
-}
-
 /* kill or nice a process */
 static void hurt_proc(int tty, int uid, int pid, const char *restrict const cmd,
               struct run_time_conf_t *run_time)
@@ -387,25 +309,6 @@ static void iterate(struct run_time_conf_t *run_time)
     closedir(d);
 }
 
-/* kill help */
-static void __attribute__ ((__noreturn__)) kill_usage(FILE * out)
-{
-    fputs(USAGE_HEADER, out);
-    fprintf(out,
-              _(" %s [options] <pid> [...]\n"), program_invocation_short_name);
-    fputs(USAGE_OPTIONS, out);
-    fputs(_(" <pid> [...]            send signal to every <pid> listed\n"), out);
-    fputs(_(" -<signal>, -s, --signal <signal>\n"
-        "                        specify the <signal> to be sent\n"), out);
-    fputs(_(" -l, --list=[<signal>]  list all signal names, or convert one to a name\n"), out);
-    fputs(_(" -L, --table            list all signal names in a nice table\n"), out);
-    fputs(USAGE_SEPARATOR, out);
-    fputs(USAGE_HELP, out);
-    fputs(USAGE_VERSION, out);
-    fprintf(out, USAGE_MAN_TAIL("kill(1)"));
-    exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
-}
-
 /* skill and snice help */
 static void __attribute__ ((__noreturn__)) skillsnice_usage(FILE * out)
 {
@@ -465,132 +368,6 @@ static void __attribute__ ((__noreturn__)) skillsnice_usage(FILE * out)
     exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
 }
 
-static int skill_sig_option(int *argc, char **argv)
-{
-    int i, nargs = *argc;
-    int signo = -1;
-    for (i = 1; i < nargs; i++) {
-        if (argv[i][0] == '-') {
-            signo = signal_name_to_number(argv[i] + 1);
-            if (-1 < signo) {
-                if (nargs - i) {
-                    nargs--;
-                    memmove(argv + i, argv + i + 1,
-                        sizeof(char *) * (nargs - i));
-                }
-                return signo;
-            }
-        }
-    }
-    return signo;
-}
-
-/* kill */
-static void __attribute__ ((__noreturn__))
-    kill_main(int argc, char **argv)
-{
-    int signo, i;
-    int sigopt = 0;
-    int loop = 1;
-    long pid;
-    int exitvalue = EXIT_SUCCESS;
-
-    static const struct option longopts[] = {
-        {"list", optional_argument, NULL, 'l'},
-        {"table", no_argument, NULL, 'L'},
-        {"signal", required_argument, NULL, 's'},
-        {"help", no_argument, NULL, 'h'},
-        {"version", no_argument, NULL, 'V'},
-        {NULL, 0, NULL, 0}
-    };
-
-    setlocale (LC_ALL, "");
-    bindtextdomain(PACKAGE, LOCALEDIR);
-    textdomain(PACKAGE);
-    atexit(close_stdout);
-
-    if (argc < 2)
-        kill_usage(stderr);
-
-    signo = skill_sig_option(&argc, argv);
-    if (signo < 0)
-        signo = SIGTERM;
-    else
-        sigopt++;
-
-    opterr=0; /* suppress errors on -123 */
-    while (loop == 1 && (i = getopt_long(argc, argv, "l::Ls:hV", longopts, NULL)) != -1)
-        switch (i) {
-        case 'l':
-            if (optarg) {
-                char *s;
-                s = strtosig(optarg);
-                if (s)
-                    printf("%s\n", s);
-                else
-                    xwarnx(_("unknown signal name %s"),
-                          optarg);
-                free(s);
-            } else {
-                unix_print_signals();
-            }
-            exit(EXIT_SUCCESS);
-        case 'L':
-            pretty_print_signals();
-            exit(EXIT_SUCCESS);
-        case 's':
-            signo = signal_name_to_number(optarg);
-            break;
-        case 'h':
-            kill_usage(stdout);
-        case 'V':
-            display_kill_version();
-            exit(EXIT_SUCCESS);
-        case '?':
-            if (!isdigit(optopt)) {
-                xwarnx(_("invalid argument %c"), optopt);
-                kill_usage(stderr);
-            } else {
-                /* Special case for signal digit negative
-                 * PIDs */
-                pid = (long)('0' - optopt);
-                if (kill((pid_t)pid, signo) != 0)
-                exitvalue = EXIT_FAILURE;
-                exit(exitvalue);
-            }
-            loop=0;
-            break;
-        default:
-            kill_usage(stderr);
-        }
-
-    argc -= optind + sigopt;
-    argv += optind;
-
-    for (i = 0; i < argc; i++) {
-        pid = strtol_or_err(argv[i], _("failed to parse argument"));
-        if (!kill((pid_t) pid, signo))
-            continue;
-        exitvalue = EXIT_FAILURE;
-        continue;
-    }
-
-    exit(exitvalue);
-}
-
-#if 0
-static void _skillsnice_usage(int line)
-{
-    fprintf(stderr, _("something at line %d\n"), line);
-    skillsnice_usage(stderr);
-}
-
-#define skillsnice_usage() _skillsnice_usage(__LINE__)
-#endif
-
-#define NEXTARG (argc?( argc--, ((argptr=*++argv)) ):NULL)
-
-/* common skill/snice argument parsing code */
 
 static int snice_prio_option(int *argc, char **argv)
 {
@@ -720,19 +497,19 @@ static void skillsnice_parse(int argc,
             ns_pid = atoi(optarg);
             if (ns_pid == 0) {
                 xwarnx(_("invalid pid number %s"), optarg);
-                kill_usage(stderr);
+                skillsnice_usage(stderr);
             }
             if (procps_ns_read_pid(ns_pid, &ns) < 0) {
                 xwarnx(_("error reading reference namespace "
                      "information"));
-                kill_usage(stderr);
+                skillsnice_usage(stderr);
             }
 
             break;
         case NSLIST_OPTION:
             if (parse_namespaces(optarg)) {
                 xwarnx(_("invalid namespace list"));
-                kill_usage(stderr);
+                skillsnice_usage(stderr);
             }
             break;
         case 'v':
@@ -744,7 +521,7 @@ static void skillsnice_parse(int argc,
         case 'h':
             skillsnice_usage(stdout);
         case 'V':
-            display_kill_version();
+            fprintf(stdout, PROCPS_NG_VERSION);
             exit(EXIT_SUCCESS);
         default:
             skillsnice_usage(stderr);
@@ -799,10 +576,7 @@ int main(int argc, char ** argv)
     memset(&run_time, 0, sizeof(struct run_time_conf_t));
     my_pid = getpid();
 
-    if (strcmp(program_invocation_short_name, "kill") == 0 ||
-        strcmp(program_invocation_short_name, "lt-kill") == 0)
-        program = PROG_KILL;
-    else if (strcmp(program_invocation_short_name, "skill") == 0 ||
+    if (strcmp(program_invocation_short_name, "skill") == 0 ||
          strcmp(program_invocation_short_name, "lt-skill") == 0)
         program = PROG_SKILL;
     else if (strcmp(program_invocation_short_name, "snice") == 0 ||
@@ -818,9 +592,6 @@ int main(int argc, char ** argv)
             show_lists();
         iterate(&run_time);
         break;
-    case PROG_KILL:
-        kill_main(argc, argv);
-        break;
     default:
         fprintf(stderr, _("skill: \"%s\" is not supported\n"),
             program_invocation_short_name);