android ueventdローカルnative部分ソースコード分析
ここにいるrc起動スクリプト
on early-init
start ueventd
ソースコードがsystem/core/init/ueventdにあるueventdが呼び出されます.c,主関数int ueventd_main(int argc,char**argv)は、以下の構造を用いる
parser.h
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.cint 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.cint 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);チェーンテーブルに