commit a32345028e7ff5899f39836f9424102af07fea0e
parent d0dc4dc2b7cdd3cabd339342d13fd994bdba2d6a
Author: sin <sin@2f30.org>
Date: Thu, 6 Mar 2014 11:13:47 +0000
Add initial version of killall5(8)
Diffstat:
M | Makefile | | | 1 | + |
A | killall5.c | | | 78 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 79 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -29,6 +29,7 @@ SRC = \
halt.c \
id.c \
insmod.c \
+ killall5.c \
lsmod.c \
lsusb.c \
mknod.c \
diff --git a/killall5.c b/killall5.c
@@ -0,0 +1,78 @@
+/* See LICENSE file for copyright and license details. */
+#include <dirent.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include "proc.h"
+#include "util.h"
+
+struct {
+ const char *name;
+ int sig;
+} sigs[] = {
+#define SIG(n) { #n, SIG##n }
+ SIG(ABRT), SIG(ALRM), SIG(BUS), SIG(CHLD), SIG(CONT), SIG(FPE), SIG(HUP),
+ SIG(ILL), SIG(INT), SIG(KILL), SIG(PIPE), SIG(QUIT), SIG(SEGV), SIG(STOP),
+ SIG(TERM), SIG(TSTP), SIG(TTIN), SIG(TTOU), SIG(USR1), SIG(USR2), SIG(URG),
+#undef SIG
+};
+
+static void
+usage(void)
+{
+ eprintf("usage: %s [-s signal]\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ DIR *dp;
+ struct dirent *entry;
+ char *end, *v;
+ int sig = SIGTERM;
+ pid_t pid;
+ size_t i;
+
+ ARGBEGIN {
+ 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) == 0) {
+ sig = sigs[i].sig;
+ break;
+ }
+ }
+ if(i == LEN(sigs))
+ eprintf("%s: unknown signal\n", v);
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if (sig != SIGSTOP && sig != SIGCONT)
+ kill(-1, SIGSTOP);
+
+ if (!(dp = opendir("/proc")))
+ eprintf("opendir /proc:");
+ while ((entry = readdir(dp))) {
+ if (!pidfile(entry->d_name))
+ continue;
+ pid = estrtol(entry->d_name, 10);
+ if (pid == 1 || pid == getpid() ||
+ getsid(pid) == getsid(0) || getsid(pid) == 0)
+ continue;
+ kill(pid, sig);
+ }
+ closedir(dp);
+
+ if (sig != SIGSTOP && sig != SIGCONT)
+ kill(-1, SIGCONT);
+
+ return EXIT_SUCCESS;
+}