您的位置:首页 > 移动开发 > Android开发

[原创]Android init.rc文件解析过程详解(二)

2015-10-19 16:25 706 查看

本文转载自 http://blog.itpub.net/7232789/viewspace-758167/
Android init.rc文件解析过程详解(二)

3、parse_new_section代码如下:

void parse_new_section(struct parse_state *state, int kw,

int nargs, char **args)
{

printf("[ %s %s ]\n", args[0],

nargs > 1 ? args[1] : "");

switch(kw) {

case K_service: \\解析service类型的section

state->context = parse_service(state, nargs, args);

if (state->context) {

state->parse_line = parse_line_service;

return;

}

break;

case K_on:
\\解析on类型的section

state->context = parse_action(state, nargs, args);

if (state->context) {

state->parse_line = parse_line_action;

return;

}

break;

case K_import:
\\解析import类型的section

parse_import(state, nargs, args);

break;

}

state->parse_line = parse_line_no_op;
}

4、parse_service()和parse_line_service()
parse_service()代码如下:
static void *parse_service(struct parse_state *state, int nargs, char **args)
{

struct service *svc;

if (nargs < 3) {

parse_error(state, "services must have a name and a program\n");

return 0;

}

if (!valid_name(args[1])) {

parse_error(state, "invalid service name '%s'\n", args[1]);

return 0;

}

svc = service_find_by_name(args[1]); //在链表中查找当前行对应的service

if (svc) {

parse_error(state, "ignored duplicate definition of service '%s'\n", args[1]);

return 0;

}

//如果当前行对应的service还没有加入service_list链表,则新建一个

nargs -= 2;

svc = calloc(1, sizeof(*svc) + sizeof(char*) * nargs);

if (!svc) {

parse_error(state, "out of memory\n");

return 0;

}

svc->name = args[1];

svc->classname = "default";

memcpy(svc->args, args + 2, sizeof(char*) * nargs);

svc->args[nargs] = 0;

svc->nargs = nargs;

svc->onrestart.name = "onrestart";

list_init(&svc->onrestart.commands);

list_add_tail(&service_list, &svc->slist); //将这个service加入到service_list
//注意此时svc对象基本上是一个空壳,因为相关的options还没有解析

return svc;
}

parse_line_service()解析service对应的options行,主要是填充parse_service()中创建的service对象。

5、parse_action()和parse_line_action()

parse_action()函数主要是根据当前行的信息创建一个action结构体类型的对象,加入到action_list双向链表中,
代码比较简单,有兴趣可自行研究。

parse_line_action()解析对应的命令行,
代码如下:

static void parse_line_action(struct parse_state* state, int nargs, char **args)
{

struct command *cmd;

struct action *act = state->context;

int (*func)(int nargs, char **args);

int kw, n;

if (nargs == 0) {

return;

}

kw = lookup_keyword(args[0]);

if (!kw_is(kw, COMMAND)) {

parse_error(state, "invalid command '%s'\n", args[0]);

return;

}

n = kw_nargs(kw);

if (nargs < n) {

parse_error(state, "%s requires %d %s\n", args[0], n - 1,

n > 2 ? "arguments" : "argument");

return;

}

cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs);
//生成一个command类型的对象

cmd->func = kw_func(kw);

cmd->nargs = nargs;

memcpy(cmd->args, args, sizeof(char*) * nargs);

list_add_tail(&act->commands, &cmd->clist); //将这个command对象加入actions->commands
}

一个on类型的section对应一个action,
action类型定义如下:

struct action {

/* node in list of all actions */

struct listnode alist;

/* node in the queue of pending actions */

struct listnode qlist;

/* node in list of actions for a trigger */

struct listnode tlist;

unsigned hash;

const char *name;

struct listnode commands; //command的双向链表

struct command *current;
};

因此,每个on类型section的第二行开始每一行都解析了一个command,
所有command组成一个双向链表指向该action的commands字段中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: