Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/procps/kill.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/procps/kill.c
r821 r1770 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * Mini kill/killall implementation for busybox3 * Mini kill/killall[5] implementation for busybox 4 4 * 5 5 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. … … 9 9 */ 10 10 11 #include "busybox.h" 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <errno.h> 15 #include <unistd.h> 16 #include <signal.h> 17 #include <ctype.h> 18 #include <string.h> 19 #include <unistd.h> 11 #include "libbb.h" 20 12 21 #define KILL 0 22 #define KILLALL 1 13 /* Note: kill_main is directly called from shell in order to implement 14 * kill built-in. Shell substitutes job ids with process groups first. 15 * 16 * This brings some complications: 17 * 18 * + we can't use xfunc here 19 * + we can't use applet_name 20 * + we can't use bb_show_usage 21 * (Above doesn't apply for killall[5] cases) 22 * 23 * kill %n gets translated into kill ' -<process group>' by shell (note space!) 24 * This is needed to avoid collision with kill -9 ... syntax 25 */ 23 26 27 int kill_main(int argc, char **argv); 24 28 int kill_main(int argc, char **argv) 25 29 { 26 int whichApp, signo = SIGTERM; 27 const char *name; 28 int errors = 0; 29 30 #ifdef CONFIG_KILLALL 31 int quiet=0; 32 /* Figure out what we are trying to do here */ 33 whichApp = (strcmp(bb_applet_name, "killall") == 0)? KILLALL : KILL; 30 char *arg; 31 pid_t pid; 32 int signo = SIGTERM, errors = 0, quiet = 0; 33 #if !ENABLE_KILLALL && !ENABLE_KILLALL5 34 #define killall 0 35 #define killall5 0 34 36 #else 35 whichApp = KILL; 37 /* How to determine who we are? find 3rd char from the end: 38 * kill, killall, killall5 39 * ^i ^a ^l - it's unique 40 * (checking from the start is complicated by /bin/kill... case) */ 41 const char char3 = argv[0][strlen(argv[0]) - 3]; 42 #define killall (ENABLE_KILLALL && char3 == 'a') 43 #define killall5 (ENABLE_KILLALL5 && char3 == 'l') 36 44 #endif 37 45 38 46 /* Parse any options */ 39 if (argc < 2)40 bb_show_usage();47 argc--; 48 arg = *++argv; 41 49 42 if(argv[1][0] != '-'){ 43 argv++; 44 argc--; 50 if (argc < 1 || arg[0] != '-') { 45 51 goto do_it_now; 46 52 } 47 53 48 /* The -l option, which prints out signal names. */ 49 if(argv[1][1]=='l' && argv[1][2]=='\0'){ 50 if(argc==2) { 54 /* The -l option, which prints out signal names. 55 * Intended usage in shell: 56 * echo "Died of SIG`kill -l $?`" 57 * We try to mimic what kill from coreutils-6.8 does */ 58 if (arg[1] == 'l' && arg[2] == '\0') { 59 if (argc == 1) { 51 60 /* Print the whole signal list */ 52 int col = 0; 53 for(signo=1; signo < NSIG; signo++) { 54 name = u_signal_names(0, &signo, 1); 55 if(name==NULL) /* unnamed */ 56 continue; 57 col += printf("%2d) %-16s", signo, name); 58 if (col > 60) { 59 printf("\n"); 60 col = 0; 61 for (signo = 1; signo < 32; signo++) { 62 const char *name = get_signame(signo); 63 if (!isdigit(name[0])) 64 puts(name); 65 } 66 } else { /* -l <sig list> */ 67 while ((arg = *++argv)) { 68 if (isdigit(arg[0])) { 69 signo = bb_strtou(arg, NULL, 10); 70 if (errno) { 71 bb_error_msg("unknown signal '%s'", arg); 72 return EXIT_FAILURE; 73 } 74 /* Exitcodes >= 0x80 are to be treated 75 * as "killed by signal (exitcode & 0x7f)" */ 76 puts(get_signame(signo & 0x7f)); 77 /* TODO: 'bad' signal# - coreutils says: 78 * kill: 127: invalid signal 79 * we just print "127" instead */ 80 } else { 81 signo = get_signum(arg); 82 if (signo < 0) { 83 bb_error_msg("unknown signal '%s'", arg); 84 return EXIT_FAILURE; 85 } 86 printf("%d\n", signo); 61 87 } 62 88 } 63 printf("\n");64 65 } else {66 for(argv++; *argv; argv++) {67 name = u_signal_names(*argv, &signo, -1);68 if(name!=NULL)69 printf("%s\n", name);70 }71 89 } 72 /* If they specified -l, we re all done */90 /* If they specified -l, we are all done */ 73 91 return EXIT_SUCCESS; 74 92 } 75 93 76 #ifdef CONFIG_KILLALL77 94 /* The -q quiet option */ 78 if (whichApp != KILL && argv[1][1]=='q' && argv[1][2]=='\0'){79 quiet ++;80 arg v++;95 if (killall && arg[1] == 'q' && arg[2] == '\0') { 96 quiet = 1; 97 arg = *++argv; 81 98 argc--; 82 if(argc<2 || argv[1][0] != '-'){ 83 goto do_it_now; 84 } 99 if (argc < 1) bb_show_usage(); 100 if (arg[0] != '-') goto do_it_now; 85 101 } 86 #endif87 102 88 if(!u_signal_names(argv[1]+1, &signo, 0)) 89 bb_error_msg_and_die( "bad signal name '%s'", argv[1]+1); 90 argv+=2; 91 argc-=2; 103 /* -SIG */ 104 signo = get_signum(&arg[1]); 105 if (signo < 0) { /* || signo > MAX_SIGNUM ? */ 106 bb_error_msg("bad signal name '%s'", &arg[1]); 107 return EXIT_FAILURE; 108 } 109 arg = *++argv; 110 argc--; 92 111 93 112 do_it_now: 94 113 95 /* Pid or name required */96 if (argc <= 0)97 bb_show_usage();114 if (killall5) { 115 pid_t sid; 116 procps_status_t* p = NULL; 98 117 99 if (whichApp == KILL) { 100 /* Looks like they want to do a kill. Do that */ 101 while (--argc >= 0) { 102 int pid; 118 /* Now stop all processes */ 119 kill(-1, SIGSTOP); 120 /* Find out our own session id */ 121 pid = getpid(); 122 sid = getsid(pid); 123 /* Now kill all processes except our session */ 124 while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID))) { 125 if (p->sid != sid && p->pid != pid && p->pid != 1) 126 kill(p->pid, signo); 127 } 128 /* And let them continue */ 129 kill(-1, SIGCONT); 130 return 0; 131 } 103 132 104 if (!isdigit(**argv) && **argv != '-') 105 bb_error_msg_and_die( "Bad PID '%s'", *argv); 106 pid = strtol(*argv, NULL, 0); 107 if (kill(pid, signo) != 0) { 108 bb_perror_msg( "Could not kill pid '%d'", pid); 133 /* Pid or name is required for kill/killall */ 134 if (argc < 1) { 135 puts("You need to specify whom to kill"); 136 return EXIT_FAILURE; 137 } 138 139 if (killall) { 140 /* Looks like they want to do a killall. Do that */ 141 pid = getpid(); 142 while (arg) { 143 pid_t* pidList; 144 145 pidList = find_pid_by_name(arg); 146 if (*pidList == 0) { 109 147 errors++; 110 } 111 argv++; 112 } 148 if (!quiet) 149 bb_error_msg("%s: no process killed", arg); 150 } else { 151 pid_t *pl; 113 152 114 } 115 #ifdef CONFIG_KILLALL 116 else { 117 pid_t myPid=getpid(); 118 /* Looks like they want to do a killall. Do that */ 119 while (--argc >= 0) { 120 long* pidList; 121 122 pidList = find_pid_by_name(*argv); 123 if (!pidList || *pidList<=0) { 124 errors++; 125 if (quiet==0) 126 bb_error_msg( "%s: no process killed", *argv); 127 } else { 128 long *pl; 129 130 for(pl = pidList; *pl !=0 ; pl++) { 131 if (*pl==myPid) 153 for (pl = pidList; *pl; pl++) { 154 if (*pl == pid) 132 155 continue; 133 if (kill(*pl, signo) != 0) {134 errors++;135 if (quiet==0)136 bb_perror_msg( "Could not kill pid '%ld'", *pl);137 }156 if (kill(*pl, signo) == 0) 157 continue; 158 errors++; 159 if (!quiet) 160 bb_perror_msg("cannot kill pid %u", (unsigned)*pl); 138 161 } 139 162 } 140 163 free(pidList); 141 arg v++;164 arg = *++argv; 142 165 } 166 return errors; 143 167 } 144 #endif 168 169 /* Looks like they want to do a kill. Do that */ 170 while (arg) { 171 /* Support shell 'space' trick */ 172 if (arg[0] == ' ') 173 arg++; 174 pid = bb_strtoi(arg, NULL, 10); 175 if (errno) { 176 bb_error_msg("bad pid '%s'", arg); 177 errors++; 178 } else if (kill(pid, signo) != 0) { 179 bb_perror_msg("cannot kill pid %d", (int)pid); 180 errors++; 181 } 182 arg = *++argv; 183 } 145 184 return errors; 146 185 }
Note:
See TracChangeset
for help on using the changeset viewer.