diff --git a/init/builtins.c b/init/builtins.c index b32981e35..c474198fc 100644 --- a/init/builtins.c +++ b/init/builtins.c @@ -48,7 +48,7 @@ #include -void add_environment(const char *name, const char *value); +int add_environment(const char *name, const char *value); extern int init_module(void *, unsigned long, const char *); @@ -261,8 +261,7 @@ int do_exec(int nargs, char **args) int do_export(int nargs, char **args) { - add_environment(args[1], args[2]); - return 0; + return add_environment(args[1], args[2]); } int do_hostname(int nargs, char **args) diff --git a/init/init.c b/init/init.c index e4ac1cf2d..74c0308bb 100644 --- a/init/init.c +++ b/init/init.c @@ -96,11 +96,24 @@ static const char *ENV[32]; /* add_environment - add "key=value" to the current environment */ int add_environment(const char *key, const char *val) { - int n; + size_t n; + size_t key_len = strlen(key); - for (n = 0; n < 31; n++) { - if (!ENV[n]) { - size_t len = strlen(key) + strlen(val) + 2; + /* The last environment entry is reserved to terminate the list */ + for (n = 0; n < (ARRAY_SIZE(ENV) - 1); n++) { + + /* Delete any existing entry for this key */ + if (ENV[n] != NULL) { + size_t entry_key_len = strcspn(ENV[n], "="); + if ((entry_key_len == key_len) && (strncmp(ENV[n], key, entry_key_len) == 0)) { + free((char*)ENV[n]); + ENV[n] = NULL; + } + } + + /* Add entry if a free slot is available */ + if (ENV[n] == NULL) { + size_t len = key_len + strlen(val) + 2; char *entry = malloc(len); snprintf(entry, len, "%s=%s", key, val); ENV[n] = entry; @@ -108,7 +121,9 @@ int add_environment(const char *key, const char *val) } } - return 1; + ERROR("No env. room to store: '%s':'%s'\n", key, val); + + return -1; } static void zap_stdio(void)