Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/procps/kill.c


Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (17 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/procps/kill.c

    r821 r1765  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * Mini kill/killall implementation for busybox
     3 * Mini kill/killall[5] implementation for busybox
    44 *
    55 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
     
    99 */
    1010
    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"
    2012
    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 */
    2326
     27int kill_main(int argc, char **argv);
    2428int kill_main(int argc, char **argv)
    2529{
    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
    3436#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')
    3644#endif
    3745
    3846    /* Parse any options */
    39     if (argc < 2)
    40         bb_show_usage();
     47    argc--;
     48    arg = *++argv;
    4149
    42     if(argv[1][0] != '-'){
    43         argv++;
    44         argc--;
     50    if (argc < 1 || arg[0] != '-') {
    4551        goto do_it_now;
    4652    }
    4753
    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) {
    5160            /* 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);
    6187                }
    6288            }
    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             }
    7189        }
    72         /* If they specified -l, were all done */
     90        /* If they specified -l, we are all done */
    7391        return EXIT_SUCCESS;
    7492    }
    7593
    76 #ifdef CONFIG_KILLALL
    7794    /* The -q quiet option */
    78     if(whichApp != KILL && argv[1][1]=='q' && argv[1][2]=='\0'){
    79         quiet++;
    80         argv++;
     95    if (killall && arg[1] == 'q' && arg[2] == '\0') {
     96        quiet = 1;
     97        arg = *++argv;
    8198        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;
    85101    }
    86 #endif
    87102
    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--;
    92111
    93112do_it_now:
    94113
    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;
    98117
    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    }
    103132
    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) {
    109147                errors++;
    110             }
    111             argv++;
    112         }
     148                if (!quiet)
     149                    bb_error_msg("%s: no process killed", arg);
     150            } else {
     151                pid_t *pl;
    113152
    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)
    132155                        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);
    138161                }
    139162            }
    140163            free(pidList);
    141             argv++;
     164            arg = *++argv;
    142165        }
     166        return errors;
    143167    }
    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    }
    145184    return errors;
    146185}
Note: See TracChangeset for help on using the changeset viewer.