Mercurial > hg > toybox
diff toys/posix/kill.c @ 1381:cae43f3cfff4 draft
Promote killall5 by merging it into kill.
Slight conflict here: this puts killall5 in the posix directory. But the commands sharing code trumps that.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sun, 06 Jul 2014 19:14:05 -0500 |
parents | 6cc69be43c42 |
children |
line wrap: on
line diff
--- a/toys/posix/kill.c Sat Jul 05 23:26:05 2014 -0500 +++ b/toys/posix/kill.c Sun Jul 06 19:14:05 2014 -0500 @@ -3,8 +3,16 @@ * Copyright 2012 Daniel Walter <d.walter@0x90.at> * * See http://opengroup.org/onlinepubs/9699919799/utilities/kill.html + * + * killall5.c - Send signal to all processes outside current session. + * + * Copyright 2014 Ranjan Kumar <ranjankumar.bth@gmail.com> + * Copyright 2014 Kyungwan Han <asura321@gamil.com> + * + * No Standard -USE_KILL(NEWTOY(kill, "?s: l", TOYFLAG_BIN)) +USE_KILL(NEWTOY(kill, "?ls: ", TOYFLAG_BIN)) +USE_KILLALL5(NEWTOY(killall5, "?o*ls: [!lo][!ls]", TOYFLAG_SBIN)) config KILL bool "kill" @@ -12,16 +20,40 @@ help usage: kill [-l [SIGNAL] | -s SIGNAL | -SIGNAL] pid... - Send a signal to a process + Send signal to process(es). + + -l List signal name(s) and number(s) + -s Send SIGNAL (default SIGTERM) + +config KILLALL5 + bool "killall5" + default y + depends on KILL + help + usage: killall5 [-l [SIGNAL]] [-SIGNAL|-s SIGNAL] [-o PID]... + + Send a signal to all processes outside current session. + + -l List signal name(s) and number(s) + -o PID Omit PID + -s send SIGNAL (default SIGTERM) */ +// This has to match the filename: #define FOR_kill #include "toys.h" GLOBALS( char *signame; + struct arg_list *olist; ) +// But kill's flags are a subset of killall5's + +#define CLEANUP_kill +#define FOR_killall5 +#include "generated/flags.h" + void kill_main(void) { int signum; @@ -53,15 +85,72 @@ error_exit("Unknown signal '%s'", arg); } else signum = SIGTERM; - if (!*args) { - toys.exithelp++; - error_exit("missing argument"); - } + // is it killall5? + if (CFG_KILLALL5 && toys.which->name[4]=='a') { + DIR *dp; + struct dirent *entry; + int pid, sid; + long *olist = 0, ocount = 0; + + // parse omit list + if (toys.optflags & FLAG_o) { + struct arg_list *ptr; + + for (ptr = TT.olist; ptr; ptr = ptr->next) ocount++; + olist = xmalloc(ocount*sizeof(long)); + ocount = 0; + for (ptr = TT.olist; ptr; ptr=ptr->next) + olist[ocount++] = atolx(ptr->arg); + } + + sid = getsid(pid = getpid()); + + if (!(dp = opendir("/proc"))) perror_exit("/proc"); + 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; - while (*args) { - char *arg = *(args++); + // Check for kernel threads. + snprintf(toybuf, sizeof(toybuf), "/proc/%d/cmdline", procpid); + if (!readfile(toybuf, toybuf, sizeof(toybuf)) || !*toybuf) continue; + + // Check with omit list. + for (count = 0; count < ocount; count++) + if (procpid == olist[count]) break; + if (count != ocount) continue; + + kill(procpid, signum); + } + if (CFG_TOYBOX_FREE) { + closedir(dp); + free(olist); + } - pid = strtol(arg, &tmp, 10); - if (*tmp || kill(pid, signum) < 0) error_msg("unknown pid '%s'", arg); + // is it kill? + } else { + + // "<1" in optstr wouldn't cover this because "-SIGNAL" + if (!*args) { + toys.exithelp++; + error_exit("missing argument"); + } + + while (*args) { + char *arg = *(args++); + + pid = strtol(arg, &tmp, 10); + if (*tmp || kill(pid, signum) < 0) error_msg("unknown pid '%s'", arg); + } } } + +void killall5_main(void) +{ + kill_main(); +}