博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[原创]Android init.rc文件解析过程详解(二)
阅读量:4046 次
发布时间:2019-05-25

本文共 3068 字,大约阅读时间需要 10 分钟。



本文转载自

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

你可能感兴趣的文章
3 张图搞懂 HBase 的存储原理.md
查看>>
一篇文章搞懂 HBase 的 flush 机制和 compact 机制
查看>>
一篇文章搞懂 HBase 的 region 拆分机制
查看>>
HBase 表的预分区是什么?为什么要预分区?如何预分区?
查看>>
Flume 是什么?Flume 有什么特点?
查看>>
一篇文章搞懂 Flume 的架构设计
查看>>
Flume 是怎么保障可靠性的?
查看>>
Flume 怎样实现数据的断点续传?
查看>>
Flume 如何自定义 Mysql Source?
查看>>
Flume 如何自定义 Mysql Sink?
查看>>
Flume 的可靠性级别有哪些?
查看>>
Sqoop 是什么?Sqoop 有什么特点?
查看>>
Sqoop 的使用场景分析
查看>>
DAGScheduler 是什么?有什么作用?
查看>>
DAGScheduler 是如何划分 Stage 的?
查看>>
TaskScheduler 是什么?有什么作用?
查看>>
一篇文章搞懂 DAGScheduler 的调度流程
查看>>
SparkEnv 是什么?有什么作用?
查看>>
SparkConf 是什么?有什么作用?
查看>>
SecurityManager 是什么?有什么作用?
查看>>