aboutsummaryrefslogtreecommitdiffstats
path: root/str_array.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2013-08-19 20:47:49 +0300
committerArnold D. Robbins <arnold@skeeve.com>2013-08-19 20:47:49 +0300
commit7d19cbd54ad60474aded4b9fe587c7f53a14d488 (patch)
tree51998aad52e56b149b5421db29924a8a8b43cf7d /str_array.c
parentf106ce81c596748a0df5b5ccca61e2f989ad9e1d (diff)
downloadegawk-7d19cbd54ad60474aded4b9fe587c7f53a14d488.tar.gz
egawk-7d19cbd54ad60474aded4b9fe587c7f53a14d488.tar.bz2
egawk-7d19cbd54ad60474aded4b9fe587c7f53a14d488.zip
Changes to ENVIRON reflect into the environment.
Diffstat (limited to 'str_array.c')
-rw-r--r--str_array.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/str_array.c b/str_array.c
index aa82d71b..e4352a9f 100644
--- a/str_array.c
+++ b/str_array.c
@@ -69,6 +69,25 @@ afunc_t str_array_func[] = {
(afunc_t) 0,
};
+static NODE **env_remove(NODE *symbol, NODE *subs);
+static NODE **env_store(NODE *symbol, NODE *subs);
+static NODE **env_clear(NODE *symbol, NODE *subs);
+
+/* special case for ENVIRON */
+afunc_t env_array_func[] = {
+ str_array_init,
+ (afunc_t) 0,
+ null_length,
+ str_lookup,
+ str_exists,
+ env_clear,
+ env_remove,
+ str_list,
+ str_copy,
+ str_dump,
+ env_store,
+};
+
static inline NODE **str_find(NODE *symbol, NODE *s1, size_t code1, unsigned long hash1);
static void grow_table(NODE *symbol);
@@ -737,3 +756,58 @@ scramble(unsigned long x)
return x;
}
+
+/* env_remove --- for ENVIRON, remove value from real environment */
+
+static NODE **
+env_remove(NODE *symbol, NODE *subs)
+{
+ NODE **val = str_remove(symbol, subs);
+
+ if (val != NULL)
+ (void) unsetenv(subs->stptr);
+
+ return val;
+}
+
+/* env_clear --- clear out the environment when ENVIRON is deleted */
+
+static NODE **
+env_clear(NODE *symbol, NODE *subs)
+{
+ extern char **environ;
+ NODE **val = str_clear(symbol, subs);
+
+ environ = NULL; /* ZAP! */
+
+ /* str_clear zaps the vtable, reset it */
+ symbol->array_funcs = env_array_func;
+
+ return val;
+}
+
+/* env_store --- post assign function for ENVIRON, put new value into env */
+
+static NODE **
+env_store(NODE *symbol, NODE *subs)
+{
+ NODE **val = str_exists(symbol, subs);
+
+ assert(val != NULL);
+
+ (void) setenv(subs->stptr, (*val)->stptr, 1);
+
+ return val;
+}
+
+/* init_env_array --- set up the pointers for ENVIRON. A bit hacky. */
+
+void
+init_env_array(NODE *env_node)
+{
+ /* If POSIX simply don't reset the vtable and things work as before */
+ if (do_posix)
+ return;
+
+ env_node->array_funcs = env_array_func;
+}