aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--init/builtins.c19
-rw-r--r--init/init_parser.c60
-rw-r--r--init/keywords.h2
3 files changed, 81 insertions, 0 deletions
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 <sys/types.h>
+#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
@@ -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 <env name> <value>
+ * 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)