Android init.rc文件解析过程详解(二)
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文件解析过程详解(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android init.rc文件解析过
- 下一篇: Android init.rc文件解析过