您的位置:首页 > 其它

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

2013-01-14 16:52 543 查看
原文: 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 (i = 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].

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: