您的位置:首页 > 产品设计 > UI/UE

android ueventd 本地native部分源码分析

2011-09-22 16:27 453 查看
在init.rc启动脚本中

on early-init

start ueventd

就会调用ueventd,其源码位于system/core/init/ueventd.c,主函数int ueventd_main(int argc, char **argv),其中用到以下结构

parser.h

//定义三个宏
#define T_EOF 0
#define T_TEXT 1
#define T_NEWLINE 2

struct parse_state
{
char *ptr;  //读指针
char *text;
int line;
int nexttoken; //下一个标识符
void *context;
void (*parse_line)(struct parse_state *state, int nargs, char **args); //读取行函数
const char *filename;
};




system/core/init/ueventd.c



int ueventd_main(int argc, char **argv)
{
struct pollfd ufd;
int nr;
char tmp[32];

open_devnull_stdio();
log_init();

INFO("starting ueventd\n");

get_hardware_name(hardware, &revision);

/*
/ueventd.rc中以行为单位,除最后sysfs properties外,每一行由四部分组成:
如:/dev/diag      0660   radio             radio
目录          权限   用户ID(uid)     组ID(gid)
# sysfs properties 多一个属性
/sys/devices/virtual/input/input*   enable      0660  root   input
目录	属性    权限   用户ID(uid)     组ID(gid)
*/
ueventd_parse_config_file("/ueventd.rc");

snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware);
ueventd_parse_config_file(tmp);

//初始化uevent,建立socket,执行coldboot,用于检查当前service启动前操作系统已经处理的事件,add这些事件到应用层
device_init();

ufd.events = POLLIN;
ufd.fd = get_device_fd();

//在死循环中处理触发事件
while(1) {
ufd.revents = 0;
nr = poll(&ufd, 1, -1);
if (nr <= 0)
continue;
if (ufd.revents == POLLIN)
handle_device_fd();
}
}
其中

ueventd_parse_config_file用于解析rc文件

Uevent_parser.c

int ueventd_parse_config_file(const char *fn)
{
char *data;
data = read_file(fn, 0); //读取文件内容返回给data
if (!data) return -1;

parse_config(fn, data);
DUMP();     //空函数什么都不做
return 0;
}

static void parse_config(const char *fn, char *s)
{
struct parse_state state;
char *args[UEVENTD_PARSER_MAXARGS];   //最多五个参数
int nargs;
nargs = 0;
state.filename = fn;
state.line = 1;
state.ptr = s;
state.nexttoken = 0;
state.parse_line = parse_line_device;
for (;;) {
int token = next_token(&state); //用于获得配置文件中特殊标记,如文件结尾(T_EOF),换行符(T_TEXT),文本(T_NEWLINE)
switch (token) {
case T_EOF:
state.parse_line(&state, 0, 0); //state.parse_line 调用函数为parse_line_device;
return;
case T_NEWLINE:
if (nargs) {
state.parse_line(&state, nargs, args);
nargs = 0;
}
break;
case T_TEXT:
if (nargs < UEVENTD_PARSER_MAXARGS) {
args[nargs++] = state.text;
}
break;
}
}
}


parser.c

int next_token(struct parse_state *state)
{
char *x = state->ptr;   //读数据指针
char *s;
/*
#define T_EOF 0
#define T_TEXT 1
#define T_NEWLINE 2
非T_EOF时,直接返回下一个标记
*/
if (state->nexttoken) {
int t = state->nexttoken;
state->nexttoken = 0;
return t;
}

for (;;) {
switch (*x) {
case 0:
state->ptr = x;
return T_EOF;
case '\n':
x++;
state->ptr = x;
return T_NEWLINE; //换行符
case ' ':
case '\t':
case '\r':
x++;
continue;  //跳过转义字符 :空格 tab 回车
case '#':
while (*x && (*x != '\n')) x++;  //单行注释
if (*x == '\n') {
state->ptr = x+1;
return T_NEWLINE;
} else {
state->ptr = x;
return T_EOF;
}
default:
goto text;
}
}

textdone:
state->ptr = x;
*s = 0;
return T_TEXT;
text:
state->text = s = x;
textresume:
for (;;) {
switch (*x) {
case 0:
goto textdone;
case ' ':
case '\t':
case '\r':
x++;
goto textdone;
case '\n':
state->nexttoken = T_NEWLINE;
x++;
goto textdone;
case '"':
x++;
for (;;) {
switch (*x) {
case 0:
/* unterminated quoted thing */
state->ptr = x;
return T_EOF;
case '"':
x++;
goto textresume;
default:
*s++ = *x++;
}
}
break;
case '\\':
x++;
switch (*x) {
case 0:
goto textdone;
case 'n':
*s++ = '\n';
break;
case 'r':
*s++ = '\r';
break;
case 't':
*s++ = '\t';
break;
case '\\':
*s++ = '\\';
break;
case '\r':
/* \ <cr> <lf> -> line continuation */
if (x[1] != '\n') {
x++;
continue;
}
case '\n':
/* \ <lf> -> line continuation */
state->line++;
x++;
/* eat any extra whitespace */
while((*x == ' ') || (*x == '\t')) x++;
continue;
default:
/* unknown escape -- just copy */
*s++ = *x++;
}
continue;
default:
*s++ = *x++;
}
}
return T_EOF;
}


static void parse_line_device(struct parse_state* state, int nargs, char **args)
{
set_device_permission(nargs, args);  //nargs参数个数 args参数
}


在此函数中根据参数个数和参数内容解析ueventd.rc,获得路径名称 属性 权限 uid gid ,

最后调用add_dev_perms(name, attr, perm, uid, gid, prefix);添加到链表
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: