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

Android init.rc文件解析过程详解(二)

 

3parse_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;

}

 

 

4parse_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对象。

 

5parse_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组成一个双向链表指向该actioncommands字段中。

 

请使用浏览器的分享功能分享到微信等