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字段中。