android ueventd 本地native部分源码分析

来源:互联网 发布:淘宝上的拍卖是真的吗 编辑:程序博客网 时间:2024/06/15 22:38

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 2struct 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);添加到链表






原创粉丝点击