From c3d69f66a69c0def357a5c373a13343e1c01ff5d Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 26 Dec 2018 11:38:04 +0100 Subject: [PATCH] efl_task: remove env from this object the env operations are moved to the efl.core.env objects, which can be used there. Differential Revision: https://phab.enlightenment.org/D7514 --- src/lib/ecore/ecore_private.h | 1 - src/lib/ecore/efl_core_env.c | 2 +- src/lib/ecore/efl_exe.c | 67 +++++++----- src/lib/ecore/efl_exe.eo | 17 +++ src/lib/ecore/efl_loop.c | 189 ---------------------------------- src/lib/ecore/efl_loop.eo | 2 - src/lib/ecore/efl_task.c | 62 +---------- src/lib/ecore/efl_task.eo | 20 ---- 8 files changed, 60 insertions(+), 300 deletions(-) diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h index c29f73d189..4e980d9123 100644 --- a/src/lib/ecore/ecore_private.h +++ b/src/lib/ecore/ecore_private.h @@ -188,7 +188,6 @@ struct _Efl_Task_Data { Eina_Stringshare *command; Eina_Array *args; - Eina_Hash *env; Efl_Task_Priority priority; int exit_code; Efl_Task_Flags flags; diff --git a/src/lib/ecore/efl_core_env.c b/src/lib/ecore/efl_core_env.c index 38fc9ba1a9..e0ee5a25e3 100644 --- a/src/lib/ecore/efl_core_env.c +++ b/src/lib/ecore/efl_core_env.c @@ -26,7 +26,7 @@ key_valid(const char *key) { if (!key || key[0] == '\0') return EINA_FALSE; - if isdigit(key[0]) return EINA_FALSE; + if (isdigit(key[0])) return EINA_FALSE; for (int i = 0; key[i] != '\0'; ++i) { if (!isalnum(key[i]) && key[i] != '_') return EINA_FALSE; diff --git a/src/lib/ecore/efl_exe.c b/src/lib/ecore/efl_exe.c index a6f9f5f506..4b3bc658d6 100644 --- a/src/lib/ecore/efl_exe.c +++ b/src/lib/ecore/efl_exe.c @@ -40,6 +40,7 @@ typedef struct _Efl_Exe_Data Efl_Exe_Data; struct _Efl_Exe_Data { + Efl_Core_Env *env; int exit_signal; Efl_Exe_Flags flags; #ifdef _WIN32 @@ -165,22 +166,6 @@ _exec(const char *cmd, Efl_Exe_Flags flags) } } -static Eina_Bool -_foreach_env(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, void *fdata EINA_UNUSED) -{ - int keylen; - char *buf, *s; - - if (!data) return EINA_TRUE; - keylen = strlen(key); - buf = alloca(keylen + 1 + strlen(data) + 1); - strcpy(buf, key); - buf[keylen] = '='; - strcpy(buf + keylen + 1, data); - if ((s = strdup(buf))) putenv(s); - return EINA_TRUE; -} - static void _exe_exit_eval(Eo *obj, Efl_Exe_Data *pd) { @@ -206,7 +191,7 @@ _exe_exit_eval(Eo *obj, Efl_Exe_Data *pd) // 128+n Fatal error signal "n" kill -9 $PPID $? returns 137 (128 + 9) // 130 Script terminated by Control-C Ctl-C Control-C is fatal error signal 2, (130 = 128 + 2, see above) // 255* Exit status out of range exit -1 exit takes only integer args in the range 0 - 255 - // + // // According to the above table, exit codes 1 - 2, // 126 - 165, and 255 [1] have special meanings, and // should therefore be avoided for user-specified exit @@ -300,6 +285,25 @@ _run_clean_cb(Efl_Loop_Consumer *consumer EINA_UNUSED, ////////////////////////////////////////////////////////////////////////// + +EOLIAN static void +_efl_exe_env_set(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd, Efl_Core_Env *env) +{ + if (pd->env == env) return; + + if (!pd->env) + efl_unref(pd->env); + pd->env = env; + if (pd->env) + efl_ref(pd->env); +} + +EOLIAN static Efl_Core_Env* +_efl_exe_env_get(const Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) +{ + return pd->env; +} + EOLIAN static void _efl_exe_signal(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd, Efl_Exe_Signal sig) { @@ -564,17 +568,28 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) // clear systemd notify socket... only relevant for systemd world, // otherwise shouldn't be trouble putenv("NOTIFY_SOCKET="); - // force the env hash to update from env vars - efl_task_env_get(loop, "HOME"); - // actually setenv the env hash (clear what was there before so it is + // actually setenv the env object (clear what was there before so it is // the only env there) -#ifdef HAVE_CLEARENV - clearenv(); -#else - environ = NULL; -#endif - eina_hash_foreach(td->env, _foreach_env, NULL); + if (pd->env) + { + Eina_Iterator *itr; + const char *key; + + #ifdef HAVE_CLEARENV + clearenv(); + #else + environ = NULL; + #endif + itr = efl_core_env_content_get(pd->env); + + EINA_ITERATOR_FOREACH(itr, key) + { + setenv(key, efl_core_env_get(pd->env, key) , 1); + } + efl_unref(pd->env); + pd->env = NULL; + } // actually execute! _exec(cmd, pd->flags); diff --git a/src/lib/ecore/efl_exe.eo b/src/lib/ecore/efl_exe.eo index d0d0cb585e..111814af21 100644 --- a/src/lib/ecore/efl_exe.eo +++ b/src/lib/ecore/efl_exe.eo @@ -42,6 +42,23 @@ class Efl.Exe extends Efl.Task implements Efl.Io.Reader, Efl.Io.Writer, Efl.Io.C sig: int; [[ The exit signal, or -1 if no exit signal happened ]] } } + @property env { + [[ If $env is $null then the process created by this object is + going to inherit the enviroment of this process. + + In case $env is not $null then the environment variables declared + in this object will represent the environment passed to the new process. + ]] + get { + [[ Get the object assosiated with this object ]] + } + set { + [[ Set the object assosiated with this object ]] + } + values { + env : Efl.Core.Env; [[$env will be referenced until this object does not need it anymore.]] + } + } } implements { Efl.Object.constructor; diff --git a/src/lib/ecore/efl_loop.c b/src/lib/ecore/efl_loop.c index 44e9c872c9..68f9573b76 100644 --- a/src/lib/ecore/efl_loop.c +++ b/src/lib/ecore/efl_loop.c @@ -15,8 +15,6 @@ #include "ecore_main_common.h" -extern char **environ; - typedef struct _Efl_Loop_Promise_Simple_Data Efl_Loop_Promise_Simple_Data; typedef struct _Efl_Internal_Promise Efl_Internal_Promise; @@ -53,11 +51,6 @@ _efl_loop_message_handler_get(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED, Efl_Loo Eo *_mainloop_singleton = NULL; Efl_Loop_Data *_mainloop_singleton_data = NULL; -extern Eina_Lock _environ_lock; -static Eina_List *_environ_strings_set = NULL; - -static void _clean_old_environ(void); - EAPI Eo * efl_main_loop_get(void) { @@ -354,16 +347,6 @@ _efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd) { pd->future_message_handler = NULL; - eina_lock_take(&_environ_lock); - _clean_old_environ(); - _environ_strings_set = eina_list_free(_environ_strings_set); - pd->env.environ_ptr = NULL; - free(pd->env.environ_copy); - pd->env.environ_copy = NULL; - eina_lock_release(&_environ_lock); - - eina_value_flush(&pd->exit_code); - efl_destructor(efl_super(obj, EFL_LOOP_CLASS)); } @@ -674,178 +657,6 @@ efl_build_version_set(int vmaj, int vmin, int vmic, int revision, _app_efl_version.build_id = build_id ? strdup(build_id) : NULL; } -static void -_env_sync(Efl_Loop_Data *pd, Efl_Task_Data *td) -{ - Eina_Bool update = EINA_FALSE; - unsigned int count = 0, i; - char **p; - - // count environs - if (environ) - { - for (p = environ; *p; p++) count++; - } - // cached env ptr is the same... so look deeper if things changes - if (pd->env.environ_ptr == environ) - { - // if we have no cached copy then update - if (!pd->env.environ_copy) update = EINA_TRUE; - else - { - // if any ptr in the cached copy doesnt match environ ptr - // then update - for (i = 0; i <= count; i++) - { - if (pd->env.environ_copy[i] != environ[i]) - { - update = EINA_TRUE; - break; - } - } - } - } - // cached env ptr changed so we need to update anyway - else update = EINA_TRUE; - if (!update) return; - // things changed - do the update - pd->env.environ_ptr = environ; - free(pd->env.environ_copy); - pd->env.environ_copy = NULL; - if (count > 0) - { - pd->env.environ_copy = malloc((count + 1) * sizeof(char *)); - if (pd->env.environ_copy) - { - for (i = 0; i <= count; i++) - pd->env.environ_copy[i] = environ[i]; - } - } - // clear previous env hash and rebuild it from environ so it matches - if (td->env) eina_hash_free(td->env); - td->env = eina_hash_string_superfast_new - ((Eina_Free_Cb)eina_stringshare_del); - for (i = 0; i < count; i++) - { - char *var; - const char *value; - - if (!environ[i]) continue; - if ((value = strchr(environ[i], '='))) - { - if (*value) - { - if ((var = malloc(value - environ[i] + 1))) - { - strncpy(var, environ[i], value - environ[i]); - var[value - environ[i]] = 0; - value++; - eina_hash_add(td->env, var, - eina_stringshare_add(value)); - free(var); - } - } - } - } -} - -static void -_clean_old_environ(void) -{ - char **p; - const char *str; - Eina_List *l, *ll; - Eina_Bool ok; - - // clean up old strings no longer in environ - EINA_LIST_FOREACH_SAFE(_environ_strings_set, l, ll, str) - { - ok = EINA_FALSE; - for (p = environ; *p; p++) - { - if (*p == str) - { - ok = EINA_TRUE; - break; - } - } - if (!ok) - { - _environ_strings_set = - eina_list_remove_list(_environ_strings_set, l); - eina_stringshare_del(str); - } - } -} - -EOLIAN static void -_efl_loop_efl_task_env_set(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, const char *var, const char *value) -{ - char *str, *str2; - size_t varlen, vallen = 0; - - if (!var) return; - - Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS); - if (!td) return; - - varlen = strlen(var); - if (value) vallen = strlen(value); - - str = malloc(varlen + 1 + vallen + 1); - if (!str) return; - strcpy(str, var); - str[varlen] = '='; - if (value) strcpy(str + varlen + 1, value); - else str[varlen + 1] = 0; - - str2 = (char *)eina_stringshare_add(str); - free(str); - if (!str2) return; - - eina_lock_take(&_environ_lock); - if (putenv(str2) != 0) - { - eina_stringshare_del(str2); - eina_lock_release(&_environ_lock); - return; - } - _environ_strings_set = eina_list_append(_environ_strings_set, str2); - eina_lock_release(&_environ_lock); - - efl_task_env_set(efl_super(obj, EFL_LOOP_CLASS), var, value); - - eina_lock_take(&_environ_lock); - _clean_old_environ(); - eina_lock_release(&_environ_lock); -} - -EOLIAN static const char * -_efl_loop_efl_task_env_get(const Eo *obj, Efl_Loop_Data *pd, const char *var) -{ - Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS); - if (!td) return NULL; - eina_lock_take(&_environ_lock); - _env_sync(pd, td); - eina_lock_release(&_environ_lock); - return efl_task_env_get(efl_super(obj, EFL_LOOP_CLASS), var); -} - -EOLIAN static void -_efl_loop_efl_task_env_reset(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd) -{ - Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS); - if (!td) return; - eina_lock_take(&_environ_lock); -#ifdef HAVE_CLEARENV - clearenv(); -#else - environ = NULL; -#endif - _env_sync(pd, td); - eina_lock_release(&_environ_lock); -} - EOLIAN static Eina_Future * _efl_loop_efl_task_run(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED) { diff --git a/src/lib/ecore/efl_loop.eo b/src/lib/ecore/efl_loop.eo index fe9cbd9a5d..7480eee867 100644 --- a/src/lib/ecore/efl_loop.eo +++ b/src/lib/ecore/efl_loop.eo @@ -125,8 +125,6 @@ class Efl.Loop extends Efl.Task Efl.Object.invalidate; Efl.Object.destructor; Efl.Object.provider_find; - Efl.Task.env { set; get; } - Efl.Task.env_reset; Efl.Task.run; Efl.Task.end; } diff --git a/src/lib/ecore/efl_task.c b/src/lib/ecore/efl_task.c index 6442669efd..311de0506a 100644 --- a/src/lib/ecore/efl_task.c +++ b/src/lib/ecore/efl_task.c @@ -227,19 +227,6 @@ _rebuild_command(Efl_Task_Data *pd) eina_strbuf_free(sb); } - -static Eina_Bool -_foreach_env_copy(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, void *fdata) -{ - if (data) - { - // only copy env vars not already set - if (!eina_hash_find(fdata, key)) - eina_hash_add(fdata, key, eina_stringshare_add(data)); - } - return EINA_TRUE; -} - ////////////////////////////////////////////////////////////////////////// EOLIAN static void @@ -322,34 +309,6 @@ _efl_task_arg_reset(Eo *obj EINA_UNUSED, Efl_Task_Data *pd) pd->command_dirty = EINA_TRUE; } -EOLIAN static void -_efl_task_env_set(Eo *obj EINA_UNUSED, Efl_Task_Data *pd, const char *var, const char *value) -{ - if (!var) return; - if (!pd->env) - pd->env = eina_hash_string_superfast_new - ((Eina_Free_Cb)eina_stringshare_del); - if (!pd->env) return; - if ((value) && (*value)) - eina_hash_add(pd->env, var, eina_stringshare_add(value)); - else eina_hash_del(pd->env, var, NULL); -} - - -EOLIAN static const char * -_efl_task_env_get(const Eo *obj EINA_UNUSED, Efl_Task_Data *pd, const char *var) -{ - if ((!var) || (!pd->env)) return NULL; - return eina_hash_find(pd->env, var); -} - -EOLIAN static void -_efl_task_env_reset(Eo *obj EINA_UNUSED, Efl_Task_Data *pd) -{ - if (pd->env) eina_hash_free(pd->env); - pd->env = NULL; -} - EOLIAN static void _efl_task_priority_set(Eo *obj EINA_UNUSED, Efl_Task_Data *pd, Efl_Task_Priority priority) { @@ -386,32 +345,13 @@ _efl_task_efl_object_destructor(Eo *obj EINA_UNUSED, Efl_Task_Data *pd) eina_stringshare_del(pd->command); pd->command = NULL; _clear_args(pd); - if (pd->env) eina_hash_free(pd->env); - pd->env = NULL; efl_destructor(efl_super(obj, MY_CLASS)); } EOLIAN static void -_efl_task_efl_object_parent_set(Eo *obj, Efl_Task_Data *pd, Efl_Object *parent) +_efl_task_efl_object_parent_set(Eo *obj, Efl_Task_Data *pd EINA_UNUSED, Efl_Object *parent) { - Eo *loop; - efl_parent_set(efl_super(obj, MY_CLASS), parent); - // copy loop env into exe task env, if not already set in env (overridden) - loop = efl_provider_find(parent, EFL_LOOP_CLASS); - if (loop) - { - Efl_Task_Data *tdl = efl_data_scope_get(loop, EFL_TASK_CLASS); - - if (tdl) - { - if (!pd->env) - pd->env = eina_hash_string_superfast_new - ((Eina_Free_Cb)eina_stringshare_del); - if (tdl->env) - eina_hash_foreach(tdl->env, _foreach_env_copy, pd->env); - } - } } ////////////////////////////////////////////////////////////////////////// diff --git a/src/lib/ecore/efl_task.eo b/src/lib/ecore/efl_task.eo index 92f0094fef..526746ff60 100644 --- a/src/lib/ecore/efl_task.eo +++ b/src/lib/ecore/efl_task.eo @@ -96,26 +96,6 @@ abstract Efl.Task extends Efl.Object [[ Clear all arguments in arg_value/count set. Will result in the command property also being cleared. ]] } - @property env { - [[ The environment to be passed in or that was passed to the - task. This is a string key, value list which map to environment - variables where appropriate. The var string must contain - only an underscore ('_'), letters ('a-z', 'A-Z'), - numbers ('0-9'), but the first character may not be a number.]] - set { } - get { } - keys { - var: string; [[ The variable name as a string ]] - } - values { - value: string; [[ Set var to this value if not $NULL, - otherwise clear this env value if value - is $NULL or if it is an empty string ]] - } - } - env_reset { - [[ Clear all environment variables. ]] - } @property priority { [[ The priority of this task. ]] get { }