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|TOYFLAG_MAYFORK)) 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] | -s 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 -s Send SIGNAL (default SIGTERM) 270f66f451Sopenharmony_ci 280f66f451Sopenharmony_ciconfig KILLALL5 290f66f451Sopenharmony_ci bool "killall5" 300f66f451Sopenharmony_ci default y 310f66f451Sopenharmony_ci depends on KILL 320f66f451Sopenharmony_ci help 330f66f451Sopenharmony_ci usage: killall5 [-l [SIGNAL]] [-SIGNAL|-s SIGNAL] [-o PID]... 340f66f451Sopenharmony_ci 350f66f451Sopenharmony_ci Send a signal to all processes outside current session. 360f66f451Sopenharmony_ci 370f66f451Sopenharmony_ci -l List signal name(s) and number(s) 380f66f451Sopenharmony_ci -o PID Omit PID 390f66f451Sopenharmony_ci -s Send SIGNAL (default SIGTERM) 400f66f451Sopenharmony_ci*/ 410f66f451Sopenharmony_ci 420f66f451Sopenharmony_ci// This has to match the filename: 430f66f451Sopenharmony_ci#define FOR_kill 440f66f451Sopenharmony_ci#define FORCE_FLAGS 450f66f451Sopenharmony_ci#include "toys.h" 460f66f451Sopenharmony_ci 470f66f451Sopenharmony_ciGLOBALS( 480f66f451Sopenharmony_ci char *s; 490f66f451Sopenharmony_ci struct arg_list *o; 500f66f451Sopenharmony_ci) 510f66f451Sopenharmony_ci 520f66f451Sopenharmony_ci// But kill's flags are a subset of killall5's 530f66f451Sopenharmony_ci 540f66f451Sopenharmony_ci#define CLEANUP_kill 550f66f451Sopenharmony_ci#define FOR_killall5 560f66f451Sopenharmony_ci#include "generated/flags.h" 570f66f451Sopenharmony_ci 580f66f451Sopenharmony_civoid kill_main(void) 590f66f451Sopenharmony_ci{ 600f66f451Sopenharmony_ci int signum; 610f66f451Sopenharmony_ci char *tmp, **args = toys.optargs; 620f66f451Sopenharmony_ci pid_t pid; 630f66f451Sopenharmony_ci 640f66f451Sopenharmony_ci // list signal(s) 650f66f451Sopenharmony_ci if (FLAG(l)) { 660f66f451Sopenharmony_ci if (*args) { 670f66f451Sopenharmony_ci int signum = sig_to_num(*args); 680f66f451Sopenharmony_ci char *s = 0; 690f66f451Sopenharmony_ci 700f66f451Sopenharmony_ci if (signum>=0) s = num_to_sig(signum&127); 710f66f451Sopenharmony_ci if (isdigit(**args)) puts(s ? s : "UNKNOWN"); 720f66f451Sopenharmony_ci else printf("%d\n", signum); 730f66f451Sopenharmony_ci } else list_signals(); 740f66f451Sopenharmony_ci 750f66f451Sopenharmony_ci return; 760f66f451Sopenharmony_ci } 770f66f451Sopenharmony_ci 780f66f451Sopenharmony_ci // signal must come before pids, so "kill -9 -1" isn't confusing. 790f66f451Sopenharmony_ci 800f66f451Sopenharmony_ci if (!TT.s && *args && **args=='-') TT.s = *(args++)+1; 810f66f451Sopenharmony_ci if (TT.s) { 820f66f451Sopenharmony_ci char *arg; 830f66f451Sopenharmony_ci int i = strtol(TT.s, &arg, 10); 840f66f451Sopenharmony_ci 850f66f451Sopenharmony_ci if (!*arg) arg = num_to_sig(i); 860f66f451Sopenharmony_ci else arg = TT.s; 870f66f451Sopenharmony_ci 880f66f451Sopenharmony_ci if (!arg || -1 == (signum = sig_to_num(arg))) 890f66f451Sopenharmony_ci error_exit("Unknown signal '%s'", arg); 900f66f451Sopenharmony_ci } else signum = SIGTERM; 910f66f451Sopenharmony_ci 920f66f451Sopenharmony_ci // is it killall5? 930f66f451Sopenharmony_ci if (CFG_KILLALL5 && toys.which->name[4]=='a') { 940f66f451Sopenharmony_ci DIR *dp; 950f66f451Sopenharmony_ci struct dirent *entry; 960f66f451Sopenharmony_ci int pid, sid; 970f66f451Sopenharmony_ci long *olist = 0, ocount = 0; 980f66f451Sopenharmony_ci 990f66f451Sopenharmony_ci // parse omit list 1000f66f451Sopenharmony_ci if (FLAG(o)) { 1010f66f451Sopenharmony_ci struct arg_list *ptr; 1020f66f451Sopenharmony_ci 1030f66f451Sopenharmony_ci for (ptr = TT.o; ptr; ptr = ptr->next) ocount++; 1040f66f451Sopenharmony_ci olist = xmalloc(ocount*sizeof(long)); 1050f66f451Sopenharmony_ci ocount = 0; 1060f66f451Sopenharmony_ci for (ptr = TT.o; ptr; ptr=ptr->next) olist[ocount++] = atolx(ptr->arg); 1070f66f451Sopenharmony_ci } 1080f66f451Sopenharmony_ci 1090f66f451Sopenharmony_ci sid = getsid(pid = getpid()); 1100f66f451Sopenharmony_ci 1110f66f451Sopenharmony_ci if (!(dp = opendir("/proc"))) { 1120f66f451Sopenharmony_ci free(olist); 1130f66f451Sopenharmony_ci perror_exit("/proc"); 1140f66f451Sopenharmony_ci } 1150f66f451Sopenharmony_ci while ((entry = readdir(dp))) { 1160f66f451Sopenharmony_ci int count, procpid, procsid; 1170f66f451Sopenharmony_ci 1180f66f451Sopenharmony_ci if (!(procpid = atoi(entry->d_name))) continue; 1190f66f451Sopenharmony_ci 1200f66f451Sopenharmony_ci snprintf(toybuf, sizeof(toybuf), "/proc/%d/stat", procpid); 1210f66f451Sopenharmony_ci if (!readfile(toybuf, toybuf, sizeof(toybuf))) continue; 1220f66f451Sopenharmony_ci if (sscanf(toybuf, "%*d %*s %*c %*d %*d %d", &procsid) != 1) continue; 1230f66f451Sopenharmony_ci if (pid == procpid || sid == procsid || procpid == 1) continue; 1240f66f451Sopenharmony_ci 1250f66f451Sopenharmony_ci // Check for kernel threads. 1260f66f451Sopenharmony_ci snprintf(toybuf, sizeof(toybuf), "/proc/%d/cmdline", procpid); 1270f66f451Sopenharmony_ci if (!readfile(toybuf, toybuf, sizeof(toybuf)) || !*toybuf) continue; 1280f66f451Sopenharmony_ci 1290f66f451Sopenharmony_ci // Check with omit list. 1300f66f451Sopenharmony_ci for (count = 0; count < ocount; count++) 1310f66f451Sopenharmony_ci if (procpid == olist[count]) break; 1320f66f451Sopenharmony_ci if (count != ocount) continue; 1330f66f451Sopenharmony_ci 1340f66f451Sopenharmony_ci kill(procpid, signum); 1350f66f451Sopenharmony_ci } 1360f66f451Sopenharmony_ci closedir(dp); 1370f66f451Sopenharmony_ci free(olist); 1380f66f451Sopenharmony_ci 1390f66f451Sopenharmony_ci // is it kill? 1400f66f451Sopenharmony_ci } else { 1410f66f451Sopenharmony_ci 1420f66f451Sopenharmony_ci // "<1" in optstr wouldn't cover this because "-SIGNAL" 1430f66f451Sopenharmony_ci if (!*args) help_exit("missing argument"); 1440f66f451Sopenharmony_ci 1450f66f451Sopenharmony_ci while (*args) { 1460f66f451Sopenharmony_ci char *arg = *(args++); 1470f66f451Sopenharmony_ci 1480f66f451Sopenharmony_ci pid = strtol(arg, &tmp, 10); 1490f66f451Sopenharmony_ci if (*tmp || kill(pid, signum) < 0) error_msg("unknown pid '%s'", arg); 1500f66f451Sopenharmony_ci } 1510f66f451Sopenharmony_ci } 1520f66f451Sopenharmony_ci} 1530f66f451Sopenharmony_ci 1540f66f451Sopenharmony_civoid killall5_main(void) 1550f66f451Sopenharmony_ci{ 1560f66f451Sopenharmony_ci kill_main(); 1570f66f451Sopenharmony_ci} 158