From be5bb1d4aa98e066c44e5ee8a54a9bf92b17aa37 Mon Sep 17 00:00:00 2001 From: David Ng Date: Wed, 4 Jan 2012 12:15:11 -0800 Subject: init: Add "export_rc" command to export env from a specified file New export_rc command to import environment variables from a specified file at the time the command is executed. Differences between "import" and "export_rc": 1) export_rc can only import environment vars 2) export_rc is performed when the command is executed rather than at the time the command is parsed (i.e. "import") Example: in /init.rc: on post-fs export_rc /system/etc/init.xyz.rc in /system/etc/init.xyz.rc: export LD_PRELOAD /system/lib/libxyz.so Change-Id: If616dea5b508c27e9f7a95b5e9db696ecea2fdee --- init/builtins.c | 19 +++++++++++++++++ init/init_parser.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ init/keywords.h | 2 ++ 3 files changed, 81 insertions(+) (limited to 'init') diff --git a/init/builtins.c b/init/builtins.c index 5dfa215e..0d87274f 100644 --- a/init/builtins.c +++ b/init/builtins.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -54,6 +55,7 @@ void add_environment(const char *name, const char *value); extern int init_module(void *, unsigned long, const char *); +extern int init_export_rc_file(const char *); static int write_file(const char *path, const char *value) { @@ -221,6 +223,23 @@ int do_class_reset(int nargs, char **args) return 0; } +int do_export_rc(int nargs, char **args) +{ + /* Import environments from a specified file. + * The file content is of the form: + * export + * e.g. + * export LD_PRELOAD /system/lib/xyz.so + * export PROMPT abcde + * Differences between "import" and "export_rc": + * 1) export_rc can only import environment vars + * 2) export_rc is performed when the command + * is executed rather than at the time the + * command is parsed (i.e. "import") + */ + return init_export_rc_file(args[1]); +} + int do_domainname(int nargs, char **args) { return write_file("/proc/sys/kernel/domainname", args[1]); diff --git a/init/init_parser.c b/init/init_parser.c index a2cd06ab..79bdbb87 100644 --- a/init/init_parser.c +++ b/init/init_parser.c @@ -51,6 +51,8 @@ static void parse_line_service(struct parse_state *state, int nargs, char **args static void *parse_action(struct parse_state *state, int nargs, char **args); static void parse_line_action(struct parse_state *state, int nargs, char **args); +void add_environment(const char *name, const char *value); + #define SECTION 0x01 #define COMMAND 0x02 #define OPTION 0x04 @@ -100,6 +102,7 @@ int lookup_keyword(const char *s) case 'e': if (!strcmp(s, "xec")) return K_exec; if (!strcmp(s, "xport")) return K_export; + if (!strcmp(s, "xport_rc")) return K_export_rc; break; case 'g': if (!strcmp(s, "roup")) return K_group; @@ -409,6 +412,63 @@ int init_parse_config_file(const char *fn) return 0; } +typedef enum { + ENV_NOTREADY, + ENV_NAME, + ENV_VALUE, + ENV_WAITFORNEXTLINE, +} export_rc_state_t; + +int init_export_rc_file(const char *fn) +{ + char *data; + struct parse_state state; + char *env = NULL; + export_rc_state_t env_state = ENV_NOTREADY; + + data = read_file(fn, 0); + if (!data) return -1; + + state.filename = fn; + state.line = 0; + state.ptr = data; + state.nexttoken = 0; + state.parse_line = parse_line_no_op; + for (;;) { + switch (next_token(&state)) { + case T_EOF: + free(data); + return 0; + case T_NEWLINE: + env_state = ENV_NOTREADY; + break; + case T_TEXT: + switch (env_state) { + case ENV_NOTREADY: + if (strcmp(state.text, "export") == 0) { + env_state = ENV_NAME; + } else { + env_state = ENV_WAITFORNEXTLINE; + } + break; + case ENV_NAME: + env = state.text; + env_state = ENV_VALUE; + break; + case ENV_VALUE: + add_environment(env, state.text); + env_state = ENV_WAITFORNEXTLINE; + break; + default: + break; + } + break; + } + } + + return 0; +} + static int valid_name(const char *name) { if (strlen(name) > 16) { diff --git a/init/keywords.h b/init/keywords.h index b3f6ebc4..66a165ff 100644 --- a/init/keywords.h +++ b/init/keywords.h @@ -8,6 +8,7 @@ int do_class_reset(int nargs, char **args); int do_domainname(int nargs, char **args); int do_exec(int nargs, char **args); int do_export(int nargs, char **args); +int do_export_rc(int nargs, char **args); int do_hostname(int nargs, char **args); int do_ifup(int nargs, char **args); int do_insmod(int nargs, char **args); @@ -55,6 +56,7 @@ enum { KEYWORD(domainname, COMMAND, 1, do_domainname) KEYWORD(exec, COMMAND, 1, do_exec) KEYWORD(export, COMMAND, 2, do_export) + KEYWORD(export_rc, COMMAND, 1, do_export_rc) KEYWORD(group, OPTION, 0, 0) KEYWORD(hostname, COMMAND, 1, do_hostname) KEYWORD(ifup, COMMAND, 1, do_ifup) -- cgit v1.2.3