Deleted Added
full compact
killall.c (125013) killall.c (132191)
1/*-
2 * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org>
3 * Copyright (c) 2000 Paul Saab <ps@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2000 Peter Wemm <peter@FreeBSD.org>
3 * Copyright (c) 2000 Paul Saab <ps@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/usr.bin/killall/killall.c 125013 2004-01-26 11:11:36Z dds $");
29__FBSDID("$FreeBSD: head/usr.bin/killall/killall.c 132191 2004-07-15 07:26:20Z tjr $");
30
31#include <sys/param.h>
32#include <sys/jail.h>
33#include <sys/stat.h>
34#include <sys/user.h>
35#include <sys/sysctl.h>
36#include <fcntl.h>
37#include <dirent.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <pwd.h>
42#include <signal.h>
43#include <regex.h>
44#include <ctype.h>
45#include <err.h>
46#include <errno.h>
47#include <unistd.h>
30
31#include <sys/param.h>
32#include <sys/jail.h>
33#include <sys/stat.h>
34#include <sys/user.h>
35#include <sys/sysctl.h>
36#include <fcntl.h>
37#include <dirent.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <pwd.h>
42#include <signal.h>
43#include <regex.h>
44#include <ctype.h>
45#include <err.h>
46#include <errno.h>
47#include <unistd.h>
48#include <locale.h>
48
49static void __dead2
50usage(void)
51{
52
53 fprintf(stderr, "usage: killall [-delmsvz] [-help] [-j jid]\n");
54 fprintf(stderr,
55 " [-u user] [-t tty] [-c cmd] [-SIGNAL] [cmd]...\n");
56 fprintf(stderr, "At least one option or argument to specify processes must be given.\n");
57 exit(1);
58}
59
60static char *
61upper(const char *str)
62{
63 static char buf[80];
64 char *s;
65
66 strncpy(buf, str, sizeof(buf));
67 buf[sizeof(buf) - 1] = '\0';
68 for (s = buf; *s; s++)
69 *s = toupper(*s);
70 return buf;
71}
72
73
74static void
75printsig(FILE *fp)
76{
77 const char *const * p;
78 int cnt;
79 int offset = 0;
80
81 for (cnt = NSIG, p = sys_signame + 1; --cnt; ++p) {
82 offset += fprintf(fp, "%s ", upper(*p));
83 if (offset >= 75 && cnt > 1) {
84 offset = 0;
85 fprintf(fp, "\n");
86 }
87 }
88 fprintf(fp, "\n");
89}
90
91static void
92nosig(char *name)
93{
94
95 warnx("unknown signal %s; valid signals:", name);
96 printsig(stderr);
97 exit(1);
98}
99
100int
101main(int ac, char **av)
102{
103 struct kinfo_proc *procs = NULL, *newprocs;
104 struct stat sb;
105 struct passwd *pw;
106 regex_t rgx;
107 regmatch_t pmatch;
108 int i, j;
109 char buf[256];
110 char *user = NULL;
111 char *tty = NULL;
112 char *cmd = NULL;
113 int vflag = 0;
114 int sflag = 0;
115 int dflag = 0;
116 int eflag = 0;
117 int jflag = 0;
118 int mflag = 0;
119 int zflag = 0;
120 uid_t uid = 0;
121 dev_t tdev = 0;
122 pid_t mypid;
123 char thiscmd[MAXCOMLEN + 1];
124 pid_t thispid;
125 uid_t thisuid;
126 dev_t thistdev;
127 int sig = SIGTERM;
128 const char *const *p;
129 char *ep;
130 int errors = 0;
131 int jid;
132 int mib[4];
133 size_t miblen;
134 int st, nprocs;
135 size_t size;
136 int matched;
137 int killed = 0;
138
49
50static void __dead2
51usage(void)
52{
53
54 fprintf(stderr, "usage: killall [-delmsvz] [-help] [-j jid]\n");
55 fprintf(stderr,
56 " [-u user] [-t tty] [-c cmd] [-SIGNAL] [cmd]...\n");
57 fprintf(stderr, "At least one option or argument to specify processes must be given.\n");
58 exit(1);
59}
60
61static char *
62upper(const char *str)
63{
64 static char buf[80];
65 char *s;
66
67 strncpy(buf, str, sizeof(buf));
68 buf[sizeof(buf) - 1] = '\0';
69 for (s = buf; *s; s++)
70 *s = toupper(*s);
71 return buf;
72}
73
74
75static void
76printsig(FILE *fp)
77{
78 const char *const * p;
79 int cnt;
80 int offset = 0;
81
82 for (cnt = NSIG, p = sys_signame + 1; --cnt; ++p) {
83 offset += fprintf(fp, "%s ", upper(*p));
84 if (offset >= 75 && cnt > 1) {
85 offset = 0;
86 fprintf(fp, "\n");
87 }
88 }
89 fprintf(fp, "\n");
90}
91
92static void
93nosig(char *name)
94{
95
96 warnx("unknown signal %s; valid signals:", name);
97 printsig(stderr);
98 exit(1);
99}
100
101int
102main(int ac, char **av)
103{
104 struct kinfo_proc *procs = NULL, *newprocs;
105 struct stat sb;
106 struct passwd *pw;
107 regex_t rgx;
108 regmatch_t pmatch;
109 int i, j;
110 char buf[256];
111 char *user = NULL;
112 char *tty = NULL;
113 char *cmd = NULL;
114 int vflag = 0;
115 int sflag = 0;
116 int dflag = 0;
117 int eflag = 0;
118 int jflag = 0;
119 int mflag = 0;
120 int zflag = 0;
121 uid_t uid = 0;
122 dev_t tdev = 0;
123 pid_t mypid;
124 char thiscmd[MAXCOMLEN + 1];
125 pid_t thispid;
126 uid_t thisuid;
127 dev_t thistdev;
128 int sig = SIGTERM;
129 const char *const *p;
130 char *ep;
131 int errors = 0;
132 int jid;
133 int mib[4];
134 size_t miblen;
135 int st, nprocs;
136 size_t size;
137 int matched;
138 int killed = 0;
139
140 setlocale(LC_ALL, "");
141
139 av++;
140 ac--;
141
142 while (ac > 0) {
143 if (strcmp(*av, "-l") == 0) {
144 printsig(stdout);
145 exit(0);
146 }
147 if (strcmp(*av, "-help") == 0)
148 usage();
149 if (**av == '-') {
150 ++*av;
151 switch (**av) {
152 case 'j':
153 ++*av;
154 if (**av == '\0')
155 ++av;
156 --ac;
157 jflag++;
158 if (!*av)
159 errx(1, "must specify jid");
160 jid = strtol(*av, &ep, 10);
161 if (!*av || *ep)
162 errx(1, "illegal jid: %s", *av);
163 if (jail_attach(jid) == -1)
164 err(1, "jail_attach(): %d", jid);
165 break;
166 case 'u':
167 ++*av;
168 if (**av == '\0')
169 ++av;
170 --ac;
171 user = *av;
172 break;
173 case 't':
174 ++*av;
175 if (**av == '\0')
176 ++av;
177 --ac;
178 tty = *av;
179 break;
180 case 'c':
181 ++*av;
182 if (**av == '\0')
183 ++av;
184 --ac;
185 cmd = *av;
186 break;
187 case 'v':
188 vflag++;
189 break;
190 case 's':
191 sflag++;
192 break;
193 case 'd':
194 dflag++;
195 break;
196 case 'e':
197 eflag++;
198 break;
199 case 'm':
200 mflag++;
201 break;
202 case 'z':
203 zflag++;
204 break;
205 default:
206 if (isalpha(**av)) {
207 if (strncasecmp(*av, "sig", 3) == 0)
208 *av += 3;
209 for (sig = NSIG, p = sys_signame + 1;
210 --sig; ++p)
211 if (strcasecmp(*p, *av) == 0) {
212 sig = p - sys_signame;
213 break;
214 }
215 if (!sig)
216 nosig(*av);
217 } else if (isdigit(**av)) {
218 sig = strtol(*av, &ep, 10);
219 if (!*av || *ep)
220 errx(1, "illegal signal number: %s", *av);
221 if (sig < 0 || sig > NSIG)
222 nosig(*av);
223 } else
224 nosig(*av);
225 }
226 ++av;
227 --ac;
228 } else {
229 break;
230 }
231 }
232
233 if (user == NULL && tty == NULL && cmd == NULL && !jflag && ac == 0)
234 usage();
235
236 if (tty) {
237 if (strncmp(tty, "/dev/", 5) == 0)
238 snprintf(buf, sizeof(buf), "%s", tty);
239 else if (strncmp(tty, "tty", 3) == 0)
240 snprintf(buf, sizeof(buf), "/dev/%s", tty);
241 else
242 snprintf(buf, sizeof(buf), "/dev/tty%s", tty);
243 if (stat(buf, &sb) < 0)
244 err(1, "stat(%s)", buf);
245 if (!S_ISCHR(sb.st_mode))
246 errx(1, "%s: not a character device", buf);
247 tdev = sb.st_rdev;
248 if (dflag)
249 printf("ttydev:0x%x\n", tdev);
250 }
251 if (user) {
252 uid = strtol(user, &ep, 10);
253 if (*user == '\0' || *ep != '\0') { /* was it a number? */
254 pw = getpwnam(user);
255 if (pw == NULL)
256 errx(1, "user %s does not exist", user);
257 uid = pw->pw_uid;
258 if (dflag)
259 printf("uid:%d\n", uid);
260 }
261 } else {
262 uid = getuid();
263 if (uid != 0) {
264 pw = getpwuid(uid);
265 if (pw)
266 user = pw->pw_name;
267 if (dflag)
268 printf("uid:%d\n", uid);
269 }
270 }
271 size = 0;
272 mib[0] = CTL_KERN;
273 mib[1] = KERN_PROC;
274 mib[2] = KERN_PROC_PROC;
275 mib[3] = 0;
276 miblen = 3;
277
278 if (user) {
279 mib[2] = eflag ? KERN_PROC_UID : KERN_PROC_RUID;
280 mib[3] = uid;
281 miblen = 4;
282 } else if (tty) {
283 mib[2] = KERN_PROC_TTY;
284 mib[3] = tdev;
285 miblen = 4;
286 }
287
288 st = sysctl(mib, miblen, NULL, &size, NULL, 0);
289 do {
290 size += size / 10;
291 newprocs = realloc(procs, size);
292 if (newprocs == 0) {
293 if (procs)
294 free(procs);
295 errx(1, "could not reallocate memory");
296 }
297 procs = newprocs;
298 st = sysctl(mib, miblen, procs, &size, NULL, 0);
299 } while (st == -1 && errno == ENOMEM);
300 if (st == -1)
301 err(1, "could not sysctl(KERN_PROC)");
302 if (size % sizeof(struct kinfo_proc) != 0) {
303 fprintf(stderr, "proc size mismatch (%d total, %d chunks)\n",
304 size, sizeof(struct kinfo_proc));
305 fprintf(stderr, "userland out of sync with kernel, recompile libkvm etc\n");
306 exit(1);
307 }
308 nprocs = size / sizeof(struct kinfo_proc);
309 if (dflag)
310 printf("nprocs %d\n", nprocs);
311 mypid = getpid();
312
313 for (i = 0; i < nprocs; i++) {
314 if ((procs[i].ki_stat & SZOMB) == SZOMB && !zflag)
315 continue;
316 thispid = procs[i].ki_pid;
317 strncpy(thiscmd, procs[i].ki_comm, MAXCOMLEN);
318 thiscmd[MAXCOMLEN] = '\0';
319 thistdev = procs[i].ki_tdev;
320 if (eflag)
321 thisuid = procs[i].ki_uid; /* effective uid */
322 else
323 thisuid = procs[i].ki_ruid; /* real uid */
324
325 if (thispid == mypid)
326 continue;
327 matched = 1;
328 if (user) {
329 if (thisuid != uid)
330 matched = 0;
331 }
332 if (tty) {
333 if (thistdev != tdev)
334 matched = 0;
335 }
336 if (cmd) {
337 if (mflag) {
338 if (regcomp(&rgx, cmd,
339 REG_EXTENDED|REG_NOSUB) != 0) {
340 mflag = 0;
341 warnx("%s: illegal regexp", cmd);
342 }
343 }
344 if (mflag) {
345 pmatch.rm_so = 0;
346 pmatch.rm_eo = strlen(thiscmd);
347 if (regexec(&rgx, thiscmd, 0, &pmatch,
348 REG_STARTEND) != 0)
349 matched = 0;
350 regfree(&rgx);
351 } else {
352 if (strncmp(thiscmd, cmd, MAXCOMLEN) != 0)
353 matched = 0;
354 }
355 }
356 if (jflag && thispid == getpid())
357 matched = 0;
358 if (matched == 0)
359 continue;
360 if (ac > 0)
361 matched = 0;
362 for (j = 0; j < ac; j++) {
363 if (mflag) {
364 if (regcomp(&rgx, av[j],
365 REG_EXTENDED|REG_NOSUB) != 0) {
366 mflag = 0;
367 warnx("%s: illegal regexp", av[j]);
368 }
369 }
370 if (mflag) {
371 pmatch.rm_so = 0;
372 pmatch.rm_eo = strlen(thiscmd);
373 if (regexec(&rgx, thiscmd, 0, &pmatch,
374 REG_STARTEND) == 0)
375 matched = 1;
376 regfree(&rgx);
377 } else {
378 if (strcmp(thiscmd, av[j]) == 0)
379 matched = 1;
380 }
381 if (matched)
382 break;
383 }
384 if (matched == 0)
385 continue;
386 if (dflag)
387 printf("sig:%d, cmd:%s, pid:%d, dev:0x%x uid:%d\n", sig,
388 thiscmd, thispid, thistdev, thisuid);
389
390 if (vflag || sflag)
391 printf("kill -%s %d\n", upper(sys_signame[sig]),
392 thispid);
393
394 killed++;
395 if (!dflag && !sflag) {
396 if (kill(thispid, sig) < 0 /* && errno != ESRCH */ ) {
397 warn("warning: kill -%s %d",
398 upper(sys_signame[sig]), thispid);
399 errors = 1;
400 }
401 }
402 }
403 if (killed == 0) {
404 fprintf(stderr, "No matching processes %swere found\n",
405 getuid() != 0 ? "belonging to you " : "");
406 errors = 1;
407 }
408 exit(errors);
409}
142 av++;
143 ac--;
144
145 while (ac > 0) {
146 if (strcmp(*av, "-l") == 0) {
147 printsig(stdout);
148 exit(0);
149 }
150 if (strcmp(*av, "-help") == 0)
151 usage();
152 if (**av == '-') {
153 ++*av;
154 switch (**av) {
155 case 'j':
156 ++*av;
157 if (**av == '\0')
158 ++av;
159 --ac;
160 jflag++;
161 if (!*av)
162 errx(1, "must specify jid");
163 jid = strtol(*av, &ep, 10);
164 if (!*av || *ep)
165 errx(1, "illegal jid: %s", *av);
166 if (jail_attach(jid) == -1)
167 err(1, "jail_attach(): %d", jid);
168 break;
169 case 'u':
170 ++*av;
171 if (**av == '\0')
172 ++av;
173 --ac;
174 user = *av;
175 break;
176 case 't':
177 ++*av;
178 if (**av == '\0')
179 ++av;
180 --ac;
181 tty = *av;
182 break;
183 case 'c':
184 ++*av;
185 if (**av == '\0')
186 ++av;
187 --ac;
188 cmd = *av;
189 break;
190 case 'v':
191 vflag++;
192 break;
193 case 's':
194 sflag++;
195 break;
196 case 'd':
197 dflag++;
198 break;
199 case 'e':
200 eflag++;
201 break;
202 case 'm':
203 mflag++;
204 break;
205 case 'z':
206 zflag++;
207 break;
208 default:
209 if (isalpha(**av)) {
210 if (strncasecmp(*av, "sig", 3) == 0)
211 *av += 3;
212 for (sig = NSIG, p = sys_signame + 1;
213 --sig; ++p)
214 if (strcasecmp(*p, *av) == 0) {
215 sig = p - sys_signame;
216 break;
217 }
218 if (!sig)
219 nosig(*av);
220 } else if (isdigit(**av)) {
221 sig = strtol(*av, &ep, 10);
222 if (!*av || *ep)
223 errx(1, "illegal signal number: %s", *av);
224 if (sig < 0 || sig > NSIG)
225 nosig(*av);
226 } else
227 nosig(*av);
228 }
229 ++av;
230 --ac;
231 } else {
232 break;
233 }
234 }
235
236 if (user == NULL && tty == NULL && cmd == NULL && !jflag && ac == 0)
237 usage();
238
239 if (tty) {
240 if (strncmp(tty, "/dev/", 5) == 0)
241 snprintf(buf, sizeof(buf), "%s", tty);
242 else if (strncmp(tty, "tty", 3) == 0)
243 snprintf(buf, sizeof(buf), "/dev/%s", tty);
244 else
245 snprintf(buf, sizeof(buf), "/dev/tty%s", tty);
246 if (stat(buf, &sb) < 0)
247 err(1, "stat(%s)", buf);
248 if (!S_ISCHR(sb.st_mode))
249 errx(1, "%s: not a character device", buf);
250 tdev = sb.st_rdev;
251 if (dflag)
252 printf("ttydev:0x%x\n", tdev);
253 }
254 if (user) {
255 uid = strtol(user, &ep, 10);
256 if (*user == '\0' || *ep != '\0') { /* was it a number? */
257 pw = getpwnam(user);
258 if (pw == NULL)
259 errx(1, "user %s does not exist", user);
260 uid = pw->pw_uid;
261 if (dflag)
262 printf("uid:%d\n", uid);
263 }
264 } else {
265 uid = getuid();
266 if (uid != 0) {
267 pw = getpwuid(uid);
268 if (pw)
269 user = pw->pw_name;
270 if (dflag)
271 printf("uid:%d\n", uid);
272 }
273 }
274 size = 0;
275 mib[0] = CTL_KERN;
276 mib[1] = KERN_PROC;
277 mib[2] = KERN_PROC_PROC;
278 mib[3] = 0;
279 miblen = 3;
280
281 if (user) {
282 mib[2] = eflag ? KERN_PROC_UID : KERN_PROC_RUID;
283 mib[3] = uid;
284 miblen = 4;
285 } else if (tty) {
286 mib[2] = KERN_PROC_TTY;
287 mib[3] = tdev;
288 miblen = 4;
289 }
290
291 st = sysctl(mib, miblen, NULL, &size, NULL, 0);
292 do {
293 size += size / 10;
294 newprocs = realloc(procs, size);
295 if (newprocs == 0) {
296 if (procs)
297 free(procs);
298 errx(1, "could not reallocate memory");
299 }
300 procs = newprocs;
301 st = sysctl(mib, miblen, procs, &size, NULL, 0);
302 } while (st == -1 && errno == ENOMEM);
303 if (st == -1)
304 err(1, "could not sysctl(KERN_PROC)");
305 if (size % sizeof(struct kinfo_proc) != 0) {
306 fprintf(stderr, "proc size mismatch (%d total, %d chunks)\n",
307 size, sizeof(struct kinfo_proc));
308 fprintf(stderr, "userland out of sync with kernel, recompile libkvm etc\n");
309 exit(1);
310 }
311 nprocs = size / sizeof(struct kinfo_proc);
312 if (dflag)
313 printf("nprocs %d\n", nprocs);
314 mypid = getpid();
315
316 for (i = 0; i < nprocs; i++) {
317 if ((procs[i].ki_stat & SZOMB) == SZOMB && !zflag)
318 continue;
319 thispid = procs[i].ki_pid;
320 strncpy(thiscmd, procs[i].ki_comm, MAXCOMLEN);
321 thiscmd[MAXCOMLEN] = '\0';
322 thistdev = procs[i].ki_tdev;
323 if (eflag)
324 thisuid = procs[i].ki_uid; /* effective uid */
325 else
326 thisuid = procs[i].ki_ruid; /* real uid */
327
328 if (thispid == mypid)
329 continue;
330 matched = 1;
331 if (user) {
332 if (thisuid != uid)
333 matched = 0;
334 }
335 if (tty) {
336 if (thistdev != tdev)
337 matched = 0;
338 }
339 if (cmd) {
340 if (mflag) {
341 if (regcomp(&rgx, cmd,
342 REG_EXTENDED|REG_NOSUB) != 0) {
343 mflag = 0;
344 warnx("%s: illegal regexp", cmd);
345 }
346 }
347 if (mflag) {
348 pmatch.rm_so = 0;
349 pmatch.rm_eo = strlen(thiscmd);
350 if (regexec(&rgx, thiscmd, 0, &pmatch,
351 REG_STARTEND) != 0)
352 matched = 0;
353 regfree(&rgx);
354 } else {
355 if (strncmp(thiscmd, cmd, MAXCOMLEN) != 0)
356 matched = 0;
357 }
358 }
359 if (jflag && thispid == getpid())
360 matched = 0;
361 if (matched == 0)
362 continue;
363 if (ac > 0)
364 matched = 0;
365 for (j = 0; j < ac; j++) {
366 if (mflag) {
367 if (regcomp(&rgx, av[j],
368 REG_EXTENDED|REG_NOSUB) != 0) {
369 mflag = 0;
370 warnx("%s: illegal regexp", av[j]);
371 }
372 }
373 if (mflag) {
374 pmatch.rm_so = 0;
375 pmatch.rm_eo = strlen(thiscmd);
376 if (regexec(&rgx, thiscmd, 0, &pmatch,
377 REG_STARTEND) == 0)
378 matched = 1;
379 regfree(&rgx);
380 } else {
381 if (strcmp(thiscmd, av[j]) == 0)
382 matched = 1;
383 }
384 if (matched)
385 break;
386 }
387 if (matched == 0)
388 continue;
389 if (dflag)
390 printf("sig:%d, cmd:%s, pid:%d, dev:0x%x uid:%d\n", sig,
391 thiscmd, thispid, thistdev, thisuid);
392
393 if (vflag || sflag)
394 printf("kill -%s %d\n", upper(sys_signame[sig]),
395 thispid);
396
397 killed++;
398 if (!dflag && !sflag) {
399 if (kill(thispid, sig) < 0 /* && errno != ESRCH */ ) {
400 warn("warning: kill -%s %d",
401 upper(sys_signame[sig]), thispid);
402 errors = 1;
403 }
404 }
405 }
406 if (killed == 0) {
407 fprintf(stderr, "No matching processes %swere found\n",
408 getuid() != 0 ? "belonging to you " : "");
409 errors = 1;
410 }
411 exit(errors);
412}