changeset 1326:78a3eaf5555f draft

killall5 - kill all the processes not in its session.
author Ashwini Sharma <ak.ashwini1981@gmail.com>
date Thu, 29 May 2014 08:21:48 -0500
parents 41fc44c76ade
children 85f297591693
files toys/pending/killall5.c
diffstat 1 files changed, 97 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toys/pending/killall5.c	Thu May 29 08:21:48 2014 -0500
@@ -0,0 +1,97 @@
+/* killall5.c - Send signal (default: TERM) to all processes outside current session.
+ *
+ * Copyright 2014 Ranjan Kumar <ranjankumar.bth@gmail.com>
+ * Copyright 2014 Kyungwan Han <asura321@gamil.com>
+ *
+ * No Standard
+
+USE_KILLALL5(NEWTOY(killall5, "?o*ls:[!lo]", TOYFLAG_SBIN))
+
+config KILLALL5
+  bool "killall5"
+  default n
+  help
+    usage: killall5 [-l] [-SIGNAL|-s SIGNAL] [-o PID]...
+
+    Send a signal (default: TERM) to all processes outside current session.
+
+    -l     List all signal names and numbers
+    -o PID Don't signal this PID
+    -s     send SIGNAL instead of SIGTERM
+*/
+#define FOR_killall5
+#include "toys.h"
+
+GLOBALS(
+  char *signame;
+  struct arg_list *olist;
+)
+
+void killall5_main(void)
+{
+  DIR *dp;
+  struct dirent *entry;
+  int signo, pid, sid, signum = SIGTERM;
+  long *olist = NULL, ocount = 0;
+  char *s, **args = toys.optargs;
+
+  // list all signal names and numbers
+  if (toys.optflags & FLAG_l) {
+    if (*args) {
+      for (; *args; args++) {
+    	signo = sig_to_num(*args);
+    	if (isdigit(**args) && (s = num_to_sig(signo&127))) xputs(s);
+    	else if (signo > 0) xprintf("%d\n", signo);
+    	else error_exit("UNKNOWN signal '%s'", *args);
+      }
+    } else sig_to_num(NULL);
+    return;
+  }
+
+  // when SIGNUM will be in the form of -SIGNUM
+  if (TT.signame || (*args && **args == '-')) {
+    if (0 > (signum = sig_to_num(TT.signame ? TT.signame : (*args)+1)))
+      error_exit("Unknown signal '%s'", *args);
+    if (!TT.signame) args++;
+  }
+  pid = getpid();
+  sid = getsid(pid);
+
+  // prepare omit list
+  if (toys.optflags & FLAG_o) {
+    struct arg_list *ptr = TT.olist;
+
+    if (*args) error_exit("invalid omit list");
+    for (; ptr; ptr=ptr->next) {
+      long val = atolx(ptr->arg);
+      olist = xrealloc(olist, (ocount+1)*sizeof(long));
+      olist[ocount++] = val;
+    }
+  }
+
+  if (!(dp = opendir("/proc"))) perror_exit("opendir");
+  while ((entry = readdir(dp))) {
+    int count, procpid, procsid;
+
+    if (!(procpid = atoi(entry->d_name))) continue;
+    snprintf(toybuf, sizeof(toybuf), "/proc/%d/stat", procpid);
+    if (!readfile(toybuf, toybuf, sizeof(toybuf))) continue;
+    if (sscanf(toybuf, "%*d %*s %*c %*d %*d %d", &procsid) != 1) continue;
+    if (pid == procpid || sid == procsid || procpid == 1) continue;
+
+    // Check for kernel threads.
+    snprintf(toybuf, sizeof(toybuf), "/proc/%d/cmdline", procpid);
+    if (readfile(toybuf, toybuf, sizeof(toybuf)) && !*toybuf) continue;
+
+    // Check with omit list.
+    if (toys.optflags & FLAG_o) {
+      for (count = 0; count < ocount; count++) {
+        if (procpid == olist[count]) goto OMIT;
+      }
+    }    
+    kill(procpid, signum);
+OMIT: ;
+  }
+  closedir(dp);
+  if (CFG_TOYBOX_FREE && olist) free(olist);
+}