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

转载:http://blog.itpub.net/7232789/viewspace-758167/

Android init.rc文件解析过程详解(二)相关推荐

  1. 安卓 linux init.rc,[原创]Android init.rc文件解析过程详解(二)

    Android init.rc文件解析过程详解(二) 3.parse_new_section代码如下: void parse_new_section(struct parse_state *state ...

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

    Android init.rc文件解析过程详解(三) 三.相关结构体 1.listnode listnode结构体用于建立双向链表,这种结构广泛用于kernel代码中, android源代码中定义了l ...

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

        Android init.rc文件解析过程详解(一) 一.init.rc文件结构介绍 init.rc文件基本组成单位是section, section分为三种类型,分别由三个关键字(所谓关键字 ...

  4. Android init.rc文件格式解析

    /****************************************************************************** Android init.rc文件格式解 ...

  5. 加载vue文件步骤_vue中.vue文件解析步骤详解

    这次给大家带来vue中.vue文件解析步骤详解,vue中.vue文件解析的注意事项有哪些,下面就是实战案例,一起来看一下. 我们平时写的 .vue 文件称为 SFC(Single File Compo ...

  6. php android 图片上传,android上传图片到PHP的过程详解

    这篇文章主要介绍了android上传图片到PHP的过程详解,需要的朋友可以参考下 今天在做上传头像的时候,总是提交连接超时错误,报错信息如下:XXXXXXSokcetTimeOutXXXXXXXX 然 ...

  7. Android签名机制之---签名验证过程详解

    一.前言 今天是元旦,也是Single Dog的嚎叫之日,只能写博客来祛除寂寞了,今天我们继续来看一下Android中的签名机制的姊妹篇:Android中是如何验证一个Apk的签名.在前一篇文章中我们 ...

  8. Android之手机文件夹目录详解

    android系统的手机文件夹目录详解 一.文件夹 1./acct/    系统回收站,删除的系统文件. 2./cache/    缓存 3./data/    用户的所有程序相关数据 app/    ...

  9. Android 系统服务管家servicemanager启动过程详解

    Android考虑到移动设备耗电以及跨进程通信效率等因素,基于OpenBinder专门为进程通信开发了一套框架:binder.例如,客户端程序需要获取WindowManager,TelephonyMa ...

最新文章

  1. 第十六届全国大学生智能车竞赛全部比赛胜利结束了
  2. PM2中无法开启ES6的解决方案
  3. 170405、java版MD5工具类
  4. Command(命令)--对象行为型模式
  5. 结构pop_宏旺半导体总结嵌入式存储封装技术SiP、SOC、MCP、PoP的区别
  6. 传奇游戏源码 Linux版本
  7. Java 解压 gzip 和 tar.gz 文件
  8. 深度解析ElasticSearch的分布式架构原理
  9. x509证书cer格式转pem格式
  10. python-sklearn实现一个简易的智能问答机器人
  11. Lucene.Net+盘古分词器(详细介绍)
  12. 认识一下身边的互联网---经典互联网书籍阅读总结
  13. 使用网址--java JPI代码示例
  14. 0xffff0000颜色表示
  15. 126邮箱OUTLOOKS设置
  16. win7计算机内存占用高,win7系统内存占用高的解决方法
  17. EXCEL中空白单元格如何快速填充为0
  18. win10局域网中设置共享文件夹
  19. 第6-3课:博弈树与井字棋(Tic-Tac-Toe)
  20. 为FLASH(.SWF)文件添加播放控制条

热门文章

  1. 拒绝干扰 解决Wi-Fi的最大问题《转》
  2. JavaScript 中的事件设计
  3. 介绍一下Objective-c常用的函数,常数变量
  4. Giphy – 分享一个很棒的 GIF 动画图片搜索引擎
  5. pku 3436 ACM Computer Factory ——最大流 EK
  6. 自己去年用intraweb写的模仿动网论坛的原程序,用的是动网论坛的数据库
  7. Windows下打印utf-8文件
  8. Windows和Virtualbox虚拟机之间拷贝文件
  9. C语言typedef和Windows数据类型
  10. javascript日期时间操作总结