Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2109779
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: Android平台

2017-01-19 16:11:53

android源码版本-->4.4.2
linux源码版本-->3.4
一. 总体分析
init_parse_config_file("/init.rc");

二.代码分析
在system/core/init/init.c中
  1. int init_parse_config_file(const char *fn)
  2. {
  3.     char *data;
  4. //将"/init.rc"的内容全部读取到以data为首指针的buffer中,函数会调用malloc(sz+2)
  5. //多分配的两个字体是结束标志,会在文件最后添加结束标志\n\0
  6.     data = read_file(fn, 0);
  7.     if (!data) return -1;

  8.     parse_config(fn, data);
  9.     DUMP();
  10.     return 0;
  11. }




在system/core/init/init_parser.c中
  1. static void parse_config(const char *fn, char *s)
  2. {
  3.     struct parse_state state;
  4.     struct listnode import_list;
  5.     struct listnode *node;
  6.     char *args[INIT_PARSER_MAXARGS];
  7.     int nargs;

  8.     nargs = 0;
  9.     state.filename = fn;
  10.     state.line = 0;
  11.     state.ptr = s;
  12.     state.nexttoken = 0;
  13.     state.parse_line = parse_line_no_op;     //这个函数的内容是空

  14.     list_init(&import_list);
  15.     state.priv = &import_list;

  16.     for (;;) {
  17.         switch (next_token(&state)) {
  18.         case T_EOF:
  19.             state.parse_line(&state, 0, 0);  //这个函数的内容是空
  20.             goto parser_done;
  21.         case T_NEWLINE:
  22.             state.line++;
  23.             if (nargs) {
  24.                 int kw = lookup_keyword(args[0]);
  25.                 if (kw_is(kw, SECTION)) {            //对service on import这三类进行处理
  26.                     state.parse_line(&state, 0, 0);  //这个函数的内容是空? 这么想就错了
  27.                     parse_new_section(&state, kw, nargs, args);
  28.                 } else {
  29.                     state.parse_line(&state, nargs, args)//这个函数的内容是空? 这么想就错了
  30.                 }
  31.                 nargs = 0;
  32.             }
  33.             break;
  34.         case T_TEXT:
  35.             if (nargs < INIT_PARSER_MAXARGS) {
  36.                 args[nargs++] = state.text;   //如果是text则放到字符串数组中,直到section结
  37.                 INFO("text=%s", state.text);  //做为section的参
  38.             }
  39.             break;
  40.         }
  41.     }

  42. parser_done:
  43.     list_for_each(node, &import_list) {
  44.          struct import *import = node_to_item(node, struct import, list);
  45.          int ret;

  46.          INFO("importing '%s'", import->filename);
  47.          ret = init_parse_config_file(import->filename);
  48.          if (ret)
  49.              ERROR("could not import file '%s' from '%s'\n",
  50.                    import->filename, fn);
  51.     }
  52. }

下面以为例说明一下对rc脚本的解析
  1. # virtual sdcard daemon running as media_rw (1023)
  2. service sdcard /system/bin/sdcard -u 1023 -g 1023 -/data/media /mnt/shell/emulated
  3. class late_start
第1步: next_token会顺序搜索service这一行,并按空格依次分隔每个字段
  1. args[0]=service
  2. args[1]=sdcard
  3. args[2]=/system/bin/sdcard
  4. args[3]=-u
  5. args[4]=1023
  6. args[5]=-g
  7. args[6]=1023
  8. args[7]=-l
  9. args[8]=/data/media
  10. args[9]=/mnt/shell/emulated
  11. 最后nargs=9,完成之后遇到\n换行符就到了case 
执行完后nargs=9,此行解析完成后遇到\n换行符,case T_NEWLINE
第2步:进入parse_new_section
  1. void parse_new_section(struct parse_state *state, int kw,
  2.                        int nargs, char **args)
  3. {
  4.     switch(kw) {
  5.     case K_service:   //因为本实例的关键字是service,所以进入parse_service
  6.         state->context = parse_service(state, nargs, args);
  7.         if (state->context) {
  8.             state->parse_line = parse_line_service;   //改函数指针
  9.             return;
  10.         }
  11.         break;
  12.     case K_on:
  13.         state->context = parse_action(state, nargs, args);
  14.         if (state->context) {
  15.             state->parse_line = parse_line_action;
  16.             return;
  17.         }
  18.         break;
  19.     case K_import:
  20.         parse_import(state, nargs, args);
  21.         break;
  22.     }
  23.     state->parse_line = parse_line_no_op;
  24. }
第3步:进入parse_service-->构造struct service并放到链表中
  1. static void *parse_service(struct parse_state *state, int nargs, char **args)
  2. {
  3.     struct service *svc;
  4.     //检查参数的个数: 最小的例子:service sdcard /system/bin/sdcard,所以最小是3个
  5.     if (nargs < 3) {
  6.         parse_error(state, "services must have a name and a program\n");
  7.         return 0;
  8.     }
  9.     //检查service_name是否合法:长度不能大于16,不能含有除字母 数字 _ - 之外的字符
  10.     if (!valid_name(args[1])) {
  11.         parse_error(state, "invalid service name '%s'\n", args[1]);
  12.         return 0;
  13.     }
  14.     //如果在service链表中找到了,说明有重名的service,这也不合法
  15.     svc = service_find_by_name(args[1]);
  16.     if (svc) {
  17.         parse_error(state, "ignored duplicate definition of service '%s'\n", args[1]);
  18.         return 0;
  19.     }
  20.     //最后构造struct service,放到链表中
  21.     nargs -= 2;
  22.     svc = calloc(1, sizeof(*svc) + sizeof(char*) * nargs);
  23.     if (!svc) {
  24.         parse_error(state, "out of memory\n");
  25.         return 0;
  26.     }
  27.     svc->name = args[1];
  28.     svc->classname = "default";
  29.     memcpy(svc->args, args + 2, sizeof(char*) * nargs);  //复制参数
  30.     svc->args[nargs] = 0;
  31.     svc->nargs = nargs;
  32.     svc->onrestart.name = "onrestart";
  33.     list_init(&svc->onrestart.commands);
  34.     list_add_tail(&service_list, &svc->slist);
  35.     return svc;
  36. }
第4步: 设置flags
  1. static void parse_line_service(struct parse_state *state, int nargs, char **args)
  2. {
  3.     svc->ioprio_class = IoSchedClass_NONE;
  4.     kw = lookup_keyword(args[0]);
  5.     switch (kw) {
  6.     case K_capability:
  7.         break;
  8.     case K_class:
  9.         if (nargs != 2) {
  10.             parse_error(state, "class option requires a classname\n");
  11.         } else {
  12.             svc->classname = args[1];
  13.         }
  14.         break;
  15.     ......
  16.     case K_oneshot:
  17.         svc->flags |= SVC_ONESHOT;     //只是改了标志位而己
  18.         break;
  19.     ....
  20.     default:
  21.         parse_error(state, "invalid option '%s'\n", args[0]);
  22.     }
  23. }



阅读(1212) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~