kill命令实现分析

参考:  android/system/core/toolbox/kill.c

首先大概了解下怎么使用kill命令:

kill  -signo   pid(pname)

kill -9 6834

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#include <sys/types.h>
#include <signal.h>


// 生成信号编号和名字字符串数组
// 编译器自动生成
static struct {
    unsigned int number;
    char *name;
} signals[] = {
#define _SIG(name) {SIG##name, #name}
    /* Single Unix Specification signals */
    _SIG(ABRT),
    _SIG(ALRM),
    _SIG(FPE),
    _SIG(HUP),
    _SIG(ILL),
    _SIG(INT),
    _SIG(KILL),
    _SIG(PIPE),
    _SIG(QUIT),
    _SIG(SEGV),
    _SIG(TERM),
    _SIG(USR1),
    _SIG(USR2),
    _SIG(CHLD),
    _SIG(CONT),
    _SIG(STOP),
    _SIG(TSTP),
    _SIG(TTIN),
    _SIG(TTOU),
    _SIG(BUS),
    _SIG(POLL),
    _SIG(PROF),
    _SIG(SYS),
    _SIG(TRAP),
    _SIG(URG),
    _SIG(VTALRM),
    _SIG(XCPU),
    _SIG(XFSZ),
    /* non-SUS signals */
    _SIG(IO),
    _SIG(PWR),
#ifdef SIGSTKFLT
    _SIG(STKFLT),
#endif
    _SIG(WINCH),
#undef _SIG
};

/* To indicate a matching signal was not found */
static const unsigned int SENTINEL = (unsigned int) -1;
void list_signals()
{
    unsigned int sorted_signals[_NSIG];
    unsigned int i;
    unsigned int num;

    memset(sorted_signals, SENTINEL, sizeof(sorted_signals));

    // 排序所有信号,从小到大
    for (i = 0; i < sizeof(signals)/sizeof(signals[0]); i++) {
        sorted_signals[signals[i].number] = i;
    }

    num = 0;
    for (i = 1; i < _NSIG; i++) {
        unsigned int index = sorted_signals[i];
        if (index == SENTINEL) {
            continue;
        }

        fprintf(stderr, "%2d) SIG%-9s ", i, signals[index].name);

        if ((num++ % 4) == 3) {
            fprintf(stderr, "\n");
        }
    }

    if ((num % 4) == 3) {
        fprintf(stderr, "\n");
    }
}
// 根据名字得到信号的索引
// 注意这个时候不区分大小写
unsigned int name_to_signal(const char* name)
{
    unsigned int i;

    for (i = 1; i < sizeof(signals) / sizeof(signals[0]); i++) {
        if (!strcasecmp(name, signals[i].name)) {
            return signals[i].number;
        }
    }

    return SENTINEL;
}
int kill_main(int argc, char **argv)
{
    //  默认信号是 : SIGTERM
    unsigned int sig = SIGTERM;
    int result = 0;

    argc--;
    argv++;

    if (argc >= 1 && argv[0][0] == '-') {
        char *endptr;
        size_t arg_len = strlen(argv[0]);
        if (arg_len < 2) {
            fprintf(stderr, "invalid argument: -\n");
            return -1;
        }
        // 从参数获得信号 number
        char* arg = argv[0] + 1;
        if (arg_len == 2 && *arg == 'l') {
		    // kill  -l
			// 显示所有可用的信号值
            list_signals();
            return 0;
        }

        sig = strtol(arg, &endptr, 10);
        if (*endptr != '\0') {
		    //  也可以输入信号的名字
            sig = name_to_signal(arg);
            if (sig == SENTINEL) {
                fprintf(stderr, "invalid signal name: %s\n", arg);
                return -1;
            }
        }
        //  下一个参数
        argc--;
        argv++;
    }
    // 可以给多个进程发送同一个信号
    while(argc > 0){
	    // 从参数获得要发送信号的进程ID
        int pid = atoi(argv[0]);
        //系统调用 kill ,触发异常,进入kernel
        int err = kill(pid, sig);
        if (err < 0) {
            result = err;
            fprintf(stderr, "could not kill pid %d: %s\n", pid, strerror(errno));
        }

        argc--;
        argv++;
    }

    return result;
}




                     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值