浅析busybox查找命令和调用相应命令函数的实现流程框架

原文: http://blog.chinaunix.net/uid-20564848-id-73422.html

busybox源码学习http://blog.chinaunix.net/uid/20564848/frmd/3729.html


浅析busybox查找命令和调用相应命令函数的实现流程框架

libbb/appletlib.c
=>main
=>applet_name = argv[0];//如果为符号链接,比如ln -s busybox ls,那么argv[0]就等于"ls"
=>applet_name = bb_basename(applet_name);//去掉绝对路径的'/‘,返回实际找到文件名给applet_name
=>parse_config_file();//调用libbb/appletlib.c中的函数
=>run_applet_and_exit

run_applet_and_exit
=>find_applet_by_name调用的是libbb/appletlib.c中的函数,
=>使用bsearch库函数,二分法、折半查找转换后的argv[0]是否为命令,因为busybox可能是经过ln符号链接了的命令,比如ln -s busybox vi
void FAST_FUNC run_applet_and_exit(const char *name, char **argv)
{
    int applet = find_applet_by_name(name);
    if (applet >= 0)//name就是命令,那么说明一定是ln -s符号链接了的命令,那么直接执行[luther.gliethttp]
        run_applet_no_and_exit(applet, argv);
    if (!strncmp(name, "busybox", 7))
        exit(busybox_main(argv));//执行到这里说明是以busybox ls方式传递的命令.
}

busybox_main
=>如果输入的为
busybox --install -s 创建所有命令的符号链接
busybox --install -h 创建所有命令的硬链接
=>autoconf.h配置文件中指定
#define CONFIG_BUSYBOX_EXEC_PATH "/proc/self/exe"
const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
install_links(busybox, argv[2] && strcmp(argv[2], "-s") == 0);
static void install_links(const char *busybox, int use_symbolic_links)
{
    /* directory table
     * this should be consistent w/ the enum,
     * busybox.h::bb_install_loc_t, or else... */

    static const char usr_bin [] ALIGN1 = "/usr/bin";
    static const char usr_sbin[] ALIGN1 = "/usr/sbin";
    static const char *const install_dir[] = {
        &usr_bin [8], /* "", equivalent to "/" for concat_path_file() */
        &usr_bin [4], /* "/bin" */
        &usr_sbin[4], /* "/sbin" */
        usr_bin,
        usr_sbin
    };

    int (*lf)(const char *, const char *);
    char *fpc;
    unsigned i;
    int rc;

    lf = link;a//库函数-硬链接
    if (use_symbolic_links)
        lf = symlink;//库函数-符号链接

    for (= 0; i < ARRAY_SIZE(applet_main); i++) {
        fpc = concat_path_file(
                install_dir[APPLET_INSTALL_LOC(i)],
//根据busybox默认的策略,计算第i个命令所应对应的安装目录[luther.gliethttp]
                APPLET_NAME(i));
        // debug: bb_error_msg("%slinking %s to busybox",
        // use_symbolic_links ? "sym" : "", fpc);
        rc = lf(busybox, fpc);//创建之
        if (rc != 0 && errno != EEXIST) {
            bb_simple_perror_msg(fpc);
        }
        free(fpc);
    }
}

=>run_applet_no_and_exit
=>exit(applet_main[applet_no](argc, argv));最终执行命令函数
void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv)
{
    int argc = 1;

    while (argv[argc])//因为前面做了argv++的调整,所以这里做一次动态计算argc值
        argc++;

    /* Reinit some shared global data */
    xfunc_error_retval = EXIT_FAILURE;

    applet_name = APPLET_NAME(applet_no);
    if (argc == 2 && strcmp(argv[1], "--help") == 0) {
        /* Special case. POSIX says "test --help"
         * should be no different from e.g. "test --foo". */

//TODO: just compare applet_no with APPLET_NO_test

        if (!ENABLE_TEST || strcmp(applet_name, "test") != 0)
            bb_show_usage();
    }
    if (ENABLE_FEATURE_SUID)
        check_suid(applet_no);
    exit(applet_main[applet_no](argc, argv));//好了执行applet_main命令数组中对应的处理函数[luther.gliethttp].
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值