Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / procmgmt / afskill.c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10 /* Kill command based on process management library (procmgmt.h).
11 * Intended for use on Windows NT, where it will only signal processes
12 * linked with the process management library (except SIGKILL).
13 */
14
15 #include <afsconfig.h>
16 #include <afs/param.h>
17 #include <afs/stds.h>
18
19 #include "procmgmt.h"
20
21 #include <roken.h>
22
23 /* Define NULL-terminated array of signal name/number pairs */
24 typedef struct {
25 char *name;
26 int number;
27 } signal_map_t;
28
29 static signal_map_t signalMap[] = {
30 {"HUP", SIGHUP},
31 {"INT", SIGINT},
32 {"QUIT", SIGQUIT},
33 {"ILL", SIGILL},
34 {"ABRT", SIGABRT},
35 {"FPE", SIGFPE},
36 {"KILL", SIGKILL},
37 {"SEGV", SIGSEGV},
38 {"TERM", SIGTERM},
39 {"USR1", SIGUSR1},
40 {"USR2", SIGUSR2},
41 {"CLD", SIGCLD},
42 {"CHLD", SIGCHLD},
43 {"TSTP", SIGTSTP},
44 {NULL, 0}
45 };
46
47
48 static void
49 PrintSignalList(void)
50 {
51 int i;
52
53 for (i = 0; signalMap[i].name; i++) {
54 printf("%s ", signalMap[i].name);
55 }
56 printf("\n");
57 }
58
59 static int
60 SignalArgToNumber(const char *sigargp)
61 {
62 long signo;
63 char *endp;
64 int i;
65
66 /* check for numeric signal arg */
67 errno = 0;
68 signo = strtol(sigargp, &endp, 0);
69
70 if (errno == 0 && *endp == '\0') {
71 return (int)signo;
72 }
73
74 /* check for named signal arg */
75 for (i = 0; signalMap[i].name; i++) {
76 if (!strcasecmp(signalMap[i].name, sigargp)) {
77 return signalMap[i].number;
78 }
79 }
80
81 return -1; /* invalid signal argument */
82 }
83
84
85 static void
86 PrintUsage(const char *whoami)
87 {
88 printf("usage: %s [-signal] [pid] ...\n", whoami);
89 printf(" %s -l\n", whoami);
90 }
91
92
93
94 int
95 main(int argc, char *argv[])
96 {
97 int status = 0;
98 char *whoami;
99
100 /* set whoami to last component of argv[0] */
101 if ((whoami = strrchr(argv[0], '/')) != NULL) {
102 whoami++;
103 } else if ((whoami = strrchr(argv[0], '\\')) != NULL) {
104 whoami++;
105 } else {
106 whoami = argv[0];
107 }
108
109 /* parse command arguments */
110 if (argc <= 1) {
111 /* no arguments; print usage statement */
112 PrintUsage(whoami);
113
114 } else if (!strcmp(argv[1], "-l")) {
115 /* request to print a list of valid signals */
116 PrintSignalList();
117
118 } else {
119 /* request to send a signal */
120 int i;
121 int signo = SIGTERM; /* SIGTERM is default if no signal specified */
122
123 for (i = 1; i < argc; i++) {
124 char *curargp = argv[i];
125
126 if (i == 1 && *curargp == '-') {
127 /* signal argument specified; translate to a number */
128 curargp++; /* advance past signal flag indicator ('-') */
129
130 if ((signo = SignalArgToNumber(curargp)) == -1) {
131 printf("%s: unknown signal %s.\n", whoami, curargp);
132 PrintUsage(whoami);
133 status = 1;
134 break;
135 }
136 } else {
137 /* pid specified; send signal */
138 long pid;
139 char *endp;
140
141 errno = 0;
142 pid = strtol(curargp, &endp, 0);
143
144 if (errno != 0 || *endp != '\0' || pid <= 0) {
145 printf("%s: invalid pid value %s.\n", whoami, curargp);
146 status = 1;
147 } else {
148 if (kill((pid_t) pid, signo)) {
149 if (errno == EINVAL) {
150 printf("%s: invalid signal number %d.\n", whoami,
151 signo);
152 status = 1;
153 break;
154
155 } else if (errno == ESRCH) {
156 printf("%s: no such process %d.\n", whoami,
157 (int)pid);
158 status = 1;
159
160 } else if (errno == EPERM) {
161 printf("%s: no privilege to signal %d.\n", whoami,
162 (int)pid);
163 status = 1;
164
165 } else {
166 printf("%s: failed to signal %d (errno = %d).\n",
167 whoami, (int)pid, (int)errno);
168 status = 1;
169 }
170 }
171 }
172 }
173 }
174 }
175
176 return status;
177 }