3.4.5 解析action
1.parse_action
解析action首先從parse_action函數開始,代碼如下:
static void parse_action(struct parse_state state, int nargs, charargs)
{
struct action act;
……//省略錯誤處理内容
act = calloc(1, sizeof(act));
act->name = args[1];
list_init(&act->commands);
/将action的指針節點放入action_list中/
list_add_tail(&action_list, &act->alist);
return act;
}
從parse_action函數的代碼可以看出,解析action的過程與解析service的過程十分相似。首先給新建立的action配置設定存儲空間,然後将action的指針節點放入一個action_list清單中。這裡又涉及兩個重要的資料類型:action結構體和action_list連結清單。
action_list與service_list都是由list_declare宏聲明,即static list_declare(action_list)。
action結構體定義在/system/core/init/init.h中,代碼如下:
struct action {
/這個指針節點所在的連結清單存儲了所有action的指針節點 /
struct listnode alist;
/這個指針節點所在的連結清單存儲了所有即将執行的action的指針節點/
struct listnode qlist;
/這個指針節點所在的連結清單存儲了所有要觸發的action的指針節點/
struct listnode tlist;
unsigned hash;
const charname;
/action對應的command/
struct listnode commands;
struct command current;
};
2.parse_line_action
熟悉了action的存儲形式,接着分析action的解析過程。定位到parse_line_action函數,該函數位于init_parser.c中,代碼如下:
static void parse_line_action(struct parse_state state, int nargs, charargs)
parse_line_action函數的執行過程很清晰,要比parse_line_service簡單很多。
這裡涉及一個重要的資料類型struct command。command結構體定義在/system/core/init/init.h中,代碼如下:
struct command
/ list of commands in an action /
struct listnode clist;
/ command對應的執行函數/
int (func)(int nargs, charargs);
int nargs;
char args[1];
至此,init.rc的解析過程便告一段落。接下來開始分析action和service的執行階段。