android ueventdローカルnative部分ソースコード分析


ここにいるrc起動スクリプト
on early-init
start ueventd
ソースコードがsystem/core/init/ueventdにある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
"); 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 '
': x++; state->ptr = x; return T_NEWLINE; // case ' ': case '\t': case '\r': x++; continue; // : tab case '#': while (*x && (*x != '
')) x++; // if (*x == '
') { 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 '
': 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++ = '
'; break; case 'r': *s++ = '\r'; break; case 't': *s++ = '\t'; break; case '\\': *s++ = '\\'; break; case '\r': /* \ <cr> <lf> -> line continuation */ if (x[1] != '
') { x++; continue; } case '
': /* \ <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);チェーンテーブルに