10f66f451Sopenharmony_ci/* kill.c - a program to send signals to processes 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2012 Daniel Walter <d.walter@0x90.at> 40f66f451Sopenharmony_ci * 50f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/kill.html 60f66f451Sopenharmony_ci * 70f66f451Sopenharmony_ci * killall5.c - Send signal to all processes outside current session. 80f66f451Sopenharmony_ci * 90f66f451Sopenharmony_ci * Copyright 2014 Ranjan Kumar <ranjankumar.bth@gmail.com> 100f66f451Sopenharmony_ci * Copyright 2014 Kyungwan Han <asura321@gamil.com> 110f66f451Sopenharmony_ci * 120f66f451Sopenharmony_ci * No Standard 130f66f451Sopenharmony_ci 140f66f451Sopenharmony_ciUSE_KILL(NEWTOY(kill, "?ls: ", TOYFLAG_BIN)) 150f66f451Sopenharmony_ciUSE_KILLALL5(NEWTOY(killall5, "?o*ls: [!lo][!ls]", TOYFLAG_SBIN)) 160f66f451Sopenharmony_ci 170f66f451Sopenharmony_ciconfig KILL 180f66f451Sopenharmony_ci bool "kill" 190f66f451Sopenharmony_ci default y 200f66f451Sopenharmony_ci help 210f66f451Sopenharmony_ci usage: kill [-l [SIGNAL] | SIGNAL | -SIGNAL] pid... 220f66f451Sopenharmony_ci 230f66f451Sopenharmony_ci Send signal to process(es). 240f66f451Sopenharmony_ci 250f66f451Sopenharmony_ci -l List signal name(s) and number(s) 260f66f451Sopenharmony_ci 270f66f451Sopenharmony_ciconfig KILLALL5 280f66f451Sopenharmony_ci bool "killall5" 290f66f451Sopenharmony_ci default n 300f66f451Sopenharmony_ci depends on KILL 310f66f451Sopenharmony_ci help 320f66f451Sopenharmony_ci usage: killall5 [-l [SIGNAL]] [-SIGNAL|-s SIGNAL] [-o PID]... 330f66f451Sopenharmony_ci 340f66f451Sopenharmony_ci Send a signal to all processes outside current session. 350f66f451Sopenharmony_ci 360f66f451Sopenharmony_ci -l List signal name(s) and number(s) 370f66f451Sopenharmony_ci -o PID Omit PID 380f66f451Sopenharmony_ci -s Send SIGNAL (default SIGTERM) 390f66f451Sopenharmony_ci*/ 400f66f451Sopenharmony_ci 410f66f451Sopenharmony_ci// This has to match the filename: 420f66f451Sopenharmony_ci#define FOR_kill 430f66f451Sopenharmony_ci#define FORCE_FLAGS 440f66f451Sopenharmony_ci#include "toys.h" 450f66f451Sopenharmony_ci 460f66f451Sopenharmony_ciGLOBALS( 470f66f451Sopenharmony_ci char *s; 480f66f451Sopenharmony_ci struct arg_list *o; 490f66f451Sopenharmony_ci) 500f66f451Sopenharmony_ci 510f66f451Sopenharmony_ci// But kill's flags are a subset of killall5's 520f66f451Sopenharmony_ci 530f66f451Sopenharmony_ci#define CLEANUP_kill 540f66f451Sopenharmony_ci#define FOR_killall5 550f66f451Sopenharmony_ci#include "generated/flags.h" 560f66f451Sopenharmony_ci 570f66f451Sopenharmony_civoid kill_main(void) 580f66f451Sopenharmony_ci{ 590f66f451Sopenharmony_ci int signum; 600f66f451Sopenharmony_ci char *tmp, **args = toys.optargs; 610f66f451Sopenharmony_ci pid_t pid; 620f66f451Sopenharmony_ci 630f66f451Sopenharmony_ci // list signal(s) 640f66f451Sopenharmony_ci if (FLAG(l)) { 650f66f451Sopenharmony_ci if (*args) { 660f66f451Sopenharmony_ci int signum = sig_to_num(*args); 670f66f451Sopenharmony_ci char *s = NULL; 680f66f451Sopenharmony_ci 690f66f451Sopenharmony_ci if (signum>=0) s = num_to_sig(signum&127); 700f66f451Sopenharmony_ci if (isdigit(**args)) puts(s ? s : "UNKNOWN"); 710f66f451Sopenharmony_ci else printf("%d\n", signum); 720f66f451Sopenharmony_ci } else list_signals(); 730f66f451Sopenharmony_ci return; 740f66f451Sopenharmony_ci } 750f66f451Sopenharmony_ci 760f66f451Sopenharmony_ci // signal must come before pids, so "kill -9 -1" isn't confusing. 770f66f451Sopenharmony_ci 780f66f451Sopenharmony_ci if (!TT.s && *args && **args=='-') TT.s = *(args++)+1; 790f66f451Sopenharmony_ci if (TT.s) { 800f66f451Sopenharmony_ci char *arg; 810f66f451Sopenharmony_ci int i = strtol(TT.s, &arg, 10); 820f66f451Sopenharmony_ci if (!*arg) arg = num_to_sig(i); 830f66f451Sopenharmony_ci else arg = TT.s; 840f66f451Sopenharmony_ci 850f66f451Sopenharmony_ci if (!arg || -1 == (signum = sig_to_num(arg))) 860f66f451Sopenharmony_ci error_exit("Unknown signal '%s'", arg); 870f66f451Sopenharmony_ci } else signum = SIGTERM; 880f66f451Sopenharmony_ci 890f66f451Sopenharmony_ci // is it killall5? 900f66f451Sopenharmony_ci if (CFG_KILLALL5 && toys.which->name[4]=='a') { 910f66f451Sopenharmony_ci DIR *dp; 920f66f451Sopenharmony_ci struct dirent *entry; 930f66f451Sopenharmony_ci int pid, sid; 940f66f451Sopenharmony_ci long *olist = 0, ocount = 0; 950f66f451Sopenharmony_ci 960f66f451Sopenharmony_ci // parse omit list 970f66f451Sopenharmony_ci if (FLAG(o)) { 980f66f451Sopenharmony_ci struct arg_list *ptr; 990f66f451Sopenharmony_ci 1000f66f451Sopenharmony_ci for (ptr = TT.o; ptr; ptr = ptr->next) ocount++; 1010f66f451Sopenharmony_ci olist = xmalloc(ocount*sizeof(long)); 1020f66f451Sopenharmony_ci ocount = 0; 1030f66f451Sopenharmony_ci for (ptr = TT.o; ptr; ptr=ptr->next) olist[ocount++] = atolx(ptr->arg); 1040f66f451Sopenharmony_ci } 1050f66f451Sopenharmony_ci 1060f66f451Sopenharmony_ci sid = getsid(pid = getpid()); 1070f66f451Sopenharmony_ci 1080f66f451Sopenharmony_ci if (!(dp = opendir("/proc"))) perror_exit("/proc"); 1090f66f451Sopenharmony_ci while ((entry = readdir(dp))) { 1100f66f451Sopenharmony_ci int count, procpid, procsid; 1110f66f451Sopenharmony_ci 1120f66f451Sopenharmony_ci if (!(procpid = atoi(entry->d_name))) continue; 1130f66f451Sopenharmony_ci 1140f66f451Sopenharmony_ci snprintf(toybuf, sizeof(toybuf), "/proc/%d/stat", procpid); 1150f66f451Sopenharmony_ci if (!readfile(toybuf, toybuf, sizeof(toybuf))) continue; 1160f66f451Sopenharmony_ci if (sscanf(toybuf, "%*d %*s %*c %*d %*d %d", &procsid) != 1) continue; 1170f66f451Sopenharmony_ci if (pid == procpid || sid == procsid || procpid == 1) continue; 1180f66f451Sopenharmony_ci 1190f66f451Sopenharmony_ci // Check for kernel threads. 1200f66f451Sopenharmony_ci snprintf(toybuf, sizeof(toybuf), "/proc/%d/cmdline", procpid); 1210f66f451Sopenharmony_ci if (!readfile(toybuf, toybuf, sizeof(toybuf)) || !*toybuf) continue; 1220f66f451Sopenharmony_ci 1230f66f451Sopenharmony_ci // Check with omit list. 1240f66f451Sopenharmony_ci for (count = 0; count < ocount; count++) 1250f66f451Sopenharmony_ci if (procpid == olist[count]) break; 1260f66f451Sopenharmony_ci if (count != ocount) continue; 1270f66f451Sopenharmony_ci 1280f66f451Sopenharmony_ci kill(procpid, signum); 1290f66f451Sopenharmony_ci } 1300f66f451Sopenharmony_ci if (CFG_TOYBOX_FREE) { 1310f66f451Sopenharmony_ci closedir(dp); 1320f66f451Sopenharmony_ci free(olist); 1330f66f451Sopenharmony_ci } 1340f66f451Sopenharmony_ci 1350f66f451Sopenharmony_ci // is it kill? 1360f66f451Sopenharmony_ci } else { 1370f66f451Sopenharmony_ci 1380f66f451Sopenharmony_ci // "<1" in optstr wouldn't cover this because "-SIGNAL" 1390f66f451Sopenharmony_ci if (!*args) help_exit("missing argument"); 1400f66f451Sopenharmony_ci 1410f66f451Sopenharmony_ci while (*args) { 1420f66f451Sopenharmony_ci char *arg = *(args++); 1430f66f451Sopenharmony_ci 1440f66f451Sopenharmony_ci pid = strtol(arg, &tmp, 10); 1450f66f451Sopenharmony_ci if (*tmp || kill(pid, signum) < 0) error_msg("unknown pid '%s'", arg); 1460f66f451Sopenharmony_ci } 1470f66f451Sopenharmony_ci } 1480f66f451Sopenharmony_ci} 1490f66f451Sopenharmony_ci 1500f66f451Sopenharmony_civoid killall5_main(void) 1510f66f451Sopenharmony_ci{ 1520f66f451Sopenharmony_ci kill_main(); 1530f66f451Sopenharmony_ci} 154