10f66f451Sopenharmony_ci/* killall.c - Send signal (default: TERM) to all processes with given names. 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2012 Andreas Heck <aheck@gmx.de> 40f66f451Sopenharmony_ci * 50f66f451Sopenharmony_ci * http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/killall.html 60f66f451Sopenharmony_ci 70f66f451Sopenharmony_ciUSE_KILLALL(NEWTOY(killall, "?s:ilqvw", TOYFLAG_USR|TOYFLAG_BIN)) 80f66f451Sopenharmony_ci 90f66f451Sopenharmony_ciconfig KILLALL 100f66f451Sopenharmony_ci bool "killall" 110f66f451Sopenharmony_ci default y 120f66f451Sopenharmony_ci help 130f66f451Sopenharmony_ci usage: killall [-l] [-iqv] [-SIGNAL|-s SIGNAL] PROCESS_NAME... 140f66f451Sopenharmony_ci 150f66f451Sopenharmony_ci Send a signal (default: TERM) to all processes with the given names. 160f66f451Sopenharmony_ci 170f66f451Sopenharmony_ci -i Ask for confirmation before killing 180f66f451Sopenharmony_ci -l Print list of all available signals 190f66f451Sopenharmony_ci -q Don't print any warnings or error messages 200f66f451Sopenharmony_ci -s Send SIGNAL instead of SIGTERM 210f66f451Sopenharmony_ci -v Report if the signal was successfully sent 220f66f451Sopenharmony_ci -w Wait until all signaled processes are dead 230f66f451Sopenharmony_ci*/ 240f66f451Sopenharmony_ci 250f66f451Sopenharmony_ci#define FOR_killall 260f66f451Sopenharmony_ci#include "toys.h" 270f66f451Sopenharmony_ci 280f66f451Sopenharmony_ciGLOBALS( 290f66f451Sopenharmony_ci char *s; 300f66f451Sopenharmony_ci 310f66f451Sopenharmony_ci int signum; 320f66f451Sopenharmony_ci pid_t cur_pid; 330f66f451Sopenharmony_ci char **names; 340f66f451Sopenharmony_ci short *err; 350f66f451Sopenharmony_ci struct int_list { struct int_list *next; int val; } *pids; 360f66f451Sopenharmony_ci) 370f66f451Sopenharmony_ci 380f66f451Sopenharmony_cistatic int kill_process(pid_t pid, char *name) 390f66f451Sopenharmony_ci{ 400f66f451Sopenharmony_ci int offset = 0; 410f66f451Sopenharmony_ci 420f66f451Sopenharmony_ci if (pid == TT.cur_pid) return 0; 430f66f451Sopenharmony_ci 440f66f451Sopenharmony_ci if (FLAG(i)) { 450f66f451Sopenharmony_ci fprintf(stderr, "Signal %s(%d)", name, (int)pid); 460f66f451Sopenharmony_ci if (!yesno(0)) return 0; 470f66f451Sopenharmony_ci } 480f66f451Sopenharmony_ci 490f66f451Sopenharmony_ci errno = 0; 500f66f451Sopenharmony_ci kill(pid, TT.signum); 510f66f451Sopenharmony_ci if (FLAG(w)) { 520f66f451Sopenharmony_ci struct int_list *new = xmalloc(sizeof(*TT.pids)); 530f66f451Sopenharmony_ci new->val = pid; 540f66f451Sopenharmony_ci new->next = TT.pids; 550f66f451Sopenharmony_ci TT.pids = new; 560f66f451Sopenharmony_ci } 570f66f451Sopenharmony_ci for (;;) { 580f66f451Sopenharmony_ci if (TT.names[offset] == name) { 590f66f451Sopenharmony_ci TT.err[offset] = errno; 600f66f451Sopenharmony_ci break; 610f66f451Sopenharmony_ci } else offset++; 620f66f451Sopenharmony_ci } 630f66f451Sopenharmony_ci if (errno) { 640f66f451Sopenharmony_ci if (!FLAG(q)) perror_msg("pid %d", (int)pid); 650f66f451Sopenharmony_ci } else if (FLAG(v)) 660f66f451Sopenharmony_ci printf("Killed %s(%d) with signal %d\n", name, pid, TT.signum); 670f66f451Sopenharmony_ci 680f66f451Sopenharmony_ci return 0; 690f66f451Sopenharmony_ci} 700f66f451Sopenharmony_ci 710f66f451Sopenharmony_civoid killall_main(void) 720f66f451Sopenharmony_ci{ 730f66f451Sopenharmony_ci int i; 740f66f451Sopenharmony_ci 750f66f451Sopenharmony_ci TT.names = toys.optargs; 760f66f451Sopenharmony_ci TT.signum = SIGTERM; 770f66f451Sopenharmony_ci 780f66f451Sopenharmony_ci if (FLAG(l)) { 790f66f451Sopenharmony_ci list_signals(); 800f66f451Sopenharmony_ci return; 810f66f451Sopenharmony_ci } 820f66f451Sopenharmony_ci 830f66f451Sopenharmony_ci if (TT.s || (*TT.names && **TT.names == '-')) { 840f66f451Sopenharmony_ci if (0 > (TT.signum = sig_to_num(TT.s ? TT.s : (*TT.names)+1))) { 850f66f451Sopenharmony_ci if (FLAG(q)) exit(1); 860f66f451Sopenharmony_ci error_exit("Invalid signal"); 870f66f451Sopenharmony_ci } 880f66f451Sopenharmony_ci if (!TT.s) { 890f66f451Sopenharmony_ci TT.names++; 900f66f451Sopenharmony_ci toys.optc--; 910f66f451Sopenharmony_ci } 920f66f451Sopenharmony_ci } 930f66f451Sopenharmony_ci 940f66f451Sopenharmony_ci if (!toys.optc) help_exit("no name"); 950f66f451Sopenharmony_ci 960f66f451Sopenharmony_ci TT.cur_pid = getpid(); 970f66f451Sopenharmony_ci 980f66f451Sopenharmony_ci TT.err = xmalloc(2*toys.optc); 990f66f451Sopenharmony_ci for (i=0; i<toys.optc; i++) TT.err[i] = ESRCH; 1000f66f451Sopenharmony_ci names_to_pid(TT.names, kill_process, 1); 1010f66f451Sopenharmony_ci for (i=0; i<toys.optc; i++) { 1020f66f451Sopenharmony_ci if (TT.err[i]) { 1030f66f451Sopenharmony_ci toys.exitval = 1; 1040f66f451Sopenharmony_ci errno = TT.err[i]; 1050f66f451Sopenharmony_ci perror_msg_raw(TT.names[i]); 1060f66f451Sopenharmony_ci } 1070f66f451Sopenharmony_ci } 1080f66f451Sopenharmony_ci if (FLAG(w)) { 1090f66f451Sopenharmony_ci for (;;) { 1100f66f451Sopenharmony_ci struct int_list *p = TT.pids; 1110f66f451Sopenharmony_ci int c = 0; 1120f66f451Sopenharmony_ci 1130f66f451Sopenharmony_ci for (; p; p=p->next) if (kill(p->val, 0) != -1 || errno != ESRCH) ++c; 1140f66f451Sopenharmony_ci if (!c) break; 1150f66f451Sopenharmony_ci sleep(1); 1160f66f451Sopenharmony_ci } 1170f66f451Sopenharmony_ci } 1180f66f451Sopenharmony_ci if (CFG_TOYBOX_FREE) { 1190f66f451Sopenharmony_ci free(TT.err); 1200f66f451Sopenharmony_ci llist_traverse(TT.pids, free); 1210f66f451Sopenharmony_ci } 1220f66f451Sopenharmony_ci} 123