diff --git a/header_checks/meson.build b/header_checks/meson.build index 066d228a83..b23e774ec1 100644 --- a/header_checks/meson.build +++ b/header_checks/meson.build @@ -53,8 +53,7 @@ header_checks = [ 'langinfo.h', 'locale.h', 'uv.h', - 'ws2tcpip.h', - 'crt_externs.h' + 'ws2tcpip.h' ] function_checks = [ diff --git a/meson.build b/meson.build index d6b9b6074d..0e2a50c2c9 100644 --- a/meson.build +++ b/meson.build @@ -210,7 +210,6 @@ elif sys_osx == true sys_lib_extension = 'dylib' sys_exe_extension = '' sys_mod_extension = 'dylib' - config_h.set('environ', '(*_NSGetEnviron())') else error('System '+host_machine.system()+' not known') endif diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am index 5f10ea7f2e..7bc8e43b74 100644 --- a/src/Makefile_Ecore.am +++ b/src/Makefile_Ecore.am @@ -49,9 +49,7 @@ ecore_eolian_files_public = \ lib/ecore/efl_boolean_model.eo \ lib/ecore/efl_select_model.eo \ lib/ecore/efl_composite_model.eo \ - lib/ecore/efl_view_model.eo \ - lib/ecore/efl_core_env.eo \ - lib/ecore/efl_core_proc_env.eo \ + lib/ecore/efl_view_model.eo ecore_eolian_files = \ $(ecore_eolian_files_legacy) \ @@ -100,8 +98,6 @@ lib/ecore/ecore_job.c \ lib/ecore/ecore_main.c \ lib/ecore/ecore_event_message.c \ lib/ecore/ecore_event_message_handler.c \ -lib/ecore/efl_core_env.c \ -lib/ecore/efl_core_proc_env.c \ lib/ecore/efl_app.c \ lib/ecore/efl_loop.c \ lib/ecore/efl_loop_consumer.c \ @@ -339,7 +335,6 @@ tests/ecore/efl_app_test_loop.c \ tests/ecore/efl_app_test_loop_fd.c \ tests/ecore/efl_app_test_loop_timer.c \ tests/ecore/efl_app_test_promise.c \ -tests/ecore/efl_app_test_env.c \ tests/ecore/efl_app_suite.c \ tests/ecore/efl_app_suite.h diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h index 348b0f5b6d..6a21ff5ea7 100644 --- a/src/lib/ecore/Ecore_Eo.h +++ b/src/lib/ecore/Ecore_Eo.h @@ -26,9 +26,6 @@ * @{ */ -#include "efl_core_env.eo.h" -#include "efl_core_proc_env.eo.h" - #include "efl_loop_message.eo.h" #include "efl_loop_message_handler.eo.h" diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h index 4e980d9123..c29f73d189 100644 --- a/src/lib/ecore/ecore_private.h +++ b/src/lib/ecore/ecore_private.h @@ -188,6 +188,7 @@ 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 e0ee5a25e3..38fc9ba1a9 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_core_env.eo b/src/lib/ecore/efl_core_env.eo deleted file mode 100644 index 86da8c14ff..0000000000 --- a/src/lib/ecore/efl_core_env.eo +++ /dev/null @@ -1,57 +0,0 @@ -class Efl.Core.Env extends Efl.Object implements Efl.Duplicate { - [[This object can maintain a set of key value pairs - - A object of this type alone does not apply the object to the system. - For getting the value into the system, see @Efl.Core.Proc_Env. - - A object can be forked, which will only copy its values, changes to the returned object will not change the object where it is forked off. - ]] - methods { - @property env { - [[ Stored var value pairs of this object. - - Var must contain only: underscores ('_'), letters ('a-z', 'A-Z'), - numbers ('0-9'), but the first character may not be a number. - ]] - set { - [[ Add a new pair to this object ]] - } - get { - [[ Get the value of the $var, or $null if no such $var exists in the object]] - } - keys { - var: string; [[ The name of the variable ]] - } - 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 ]] - } - } - unset { - [[ Remove the pair with the matching $var from this object]] - params { - var : string; [[ The name of the variable ]] - } - } - clear { - [[ Remove all pairs from this object]] - } - @property content { - [[ Get the content of this object. - - This will return a iterator that contains all keys that are part of this object. - ]] - get { - - } - values { - iter : iterator; - } - } - } - implements { - Efl.Object.constructor; - Efl.Duplicate.duplicate; - } -} diff --git a/src/lib/ecore/efl_core_proc_env.c b/src/lib/ecore/efl_core_proc_env.c deleted file mode 100644 index 846b69a350..0000000000 --- a/src/lib/ecore/efl_core_proc_env.c +++ /dev/null @@ -1,145 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#ifdef HAVE_CRT_EXTERNS_H -# include -#endif -#include "ecore_private.h" - -#define MY_CLASS EFL_CORE_PROC_ENV_CLASS - -static Efl_Core_Env *env = NULL; - -typedef struct { - Eina_Bool in_sync; -} Efl_Core_Proc_Env_Data; - -static void -_sync(Efl_Core_Env *obj, Efl_Core_Proc_Env_Data *pd) -{ - Eina_List *existing_keys = NULL, *n; - Eina_Iterator *content; - const char *key; - - pd->in_sync = EINA_TRUE; - content = efl_core_env_content_get(obj); - - EINA_ITERATOR_FOREACH(content, key) - { - existing_keys = eina_list_append(existing_keys, key); - } - - if (environ) - { - char **p; - - for (p = environ; *p; p++) - { - char **values; - - values = eina_str_split(*p, "=", 2); - efl_core_env_set(obj, values[0], values[1]); - - EINA_LIST_FOREACH(existing_keys, n, key) - { - if (!strcmp(key, values[0])) - { - existing_keys = eina_list_remove_list(existing_keys, n); - break; - } - } - } - } - EINA_LIST_FOREACH(existing_keys, n, key) - { - efl_core_env_unset(obj, key); - } - pd->in_sync = EINA_FALSE; -} - -EOLIAN static const char* -_efl_core_proc_env_efl_core_env_env_get(const Eo *obj, Efl_Core_Proc_Env_Data *pd, const char *var) -{ - if (!pd->in_sync) - _sync((Eo*)obj, pd); - return efl_core_env_get(efl_super(obj, MY_CLASS), var); -} - -EOLIAN static void -_efl_core_proc_env_efl_core_env_env_set(Eo *obj, Efl_Core_Proc_Env_Data *pd, const char *var, const char *value) -{ - efl_core_env_set(efl_super(obj, MY_CLASS), var, value); - if (!pd->in_sync) - { - if (value) - setenv(var, value, 1); - else - unsetenv(var); - } -} - -EOLIAN static void -_efl_core_proc_env_efl_core_env_unset(Eo *obj, Efl_Core_Proc_Env_Data *pd, const char *key) -{ - efl_core_env_unset(efl_super(obj, MY_CLASS), key); - if (!pd->in_sync) - { - unsetenv(key); - } -} - -EOLIAN static void -_efl_core_proc_env_efl_core_env_clear(Eo *obj, Efl_Core_Proc_Env_Data *pd) -{ - efl_core_env_clear(efl_super(obj, MY_CLASS)); - if (!pd->in_sync) - { -#ifdef HAVE_CLEARENV - clearenv(); -#else - environ = NULL; -#endif - } -} - - -EOLIAN static Efl_Duplicate* -_efl_core_proc_env_efl_duplicate_duplicate(const Eo *obj, Efl_Core_Proc_Env_Data *pd) -{ - if (!pd->in_sync) - _sync((Eo*) obj, pd); - return efl_duplicate(efl_super(obj, MY_CLASS)); -} - -EOLIAN static Eina_Iterator* -_efl_core_proc_env_efl_core_env_content_get(const Eo *obj, Efl_Core_Proc_Env_Data *pd) -{ - if (!pd->in_sync) - _sync((Eo*) obj, pd); - return efl_core_env_content_get(efl_super(obj, MY_CLASS)); -} - -EOLIAN static Efl_Object* -_efl_core_proc_env_efl_object_constructor(Eo *obj, Efl_Core_Proc_Env_Data *pd EINA_UNUSED) -{ - EINA_SAFETY_ON_TRUE_RETURN_VAL(!!env, NULL); - - obj = efl_constructor(efl_super(obj, MY_CLASS)); - return obj; -} - -EOLIAN static Efl_Core_Env* -_efl_core_proc_env_self(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED) -{ - if (!env) - { - env = efl_add_ref(EFL_CORE_PROC_ENV_CLASS, NULL); - efl_wref_add(env, &env); - } - - return env; -} - -#include "efl_core_proc_env.eo.c" diff --git a/src/lib/ecore/efl_core_proc_env.eo b/src/lib/ecore/efl_core_proc_env.eo deleted file mode 100644 index 23c2c67d75..0000000000 --- a/src/lib/ecore/efl_core_proc_env.eo +++ /dev/null @@ -1,21 +0,0 @@ -class Efl.Core.Proc_Env extends Efl.Core.Env -{ - eo_prefix : efl_env; - methods { - self @class { - [[Get a instance of this object - - The object will apply the environment operations onto this process. - ]] - return : Efl.Core.Env; - } - } - implements { - Efl.Core.Env.env { set; get; } - Efl.Core.Env.content { get; } - Efl.Core.Env.unset; - Efl.Core.Env.clear; - Efl.Duplicate.duplicate; - Efl.Object.constructor; - } -} diff --git a/src/lib/ecore/efl_exe.c b/src/lib/ecore/efl_exe.c index 4b3bc658d6..a6f9f5f506 100644 --- a/src/lib/ecore/efl_exe.c +++ b/src/lib/ecore/efl_exe.c @@ -40,7 +40,6 @@ 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 @@ -166,6 +165,22 @@ _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) { @@ -191,7 +206,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 @@ -285,25 +300,6 @@ _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) { @@ -568,28 +564,17 @@ _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 object (clear what was there before so it is + // actually setenv the env hash (clear what was there before so it is // the only env there) - 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; - } +#ifdef HAVE_CLEARENV + clearenv(); +#else + environ = NULL; +#endif + eina_hash_foreach(td->env, _foreach_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 111814af21..d0d0cb585e 100644 --- a/src/lib/ecore/efl_exe.eo +++ b/src/lib/ecore/efl_exe.eo @@ -42,23 +42,6 @@ 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 68f9573b76..44e9c872c9 100644 --- a/src/lib/ecore/efl_loop.c +++ b/src/lib/ecore/efl_loop.c @@ -15,6 +15,8 @@ #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; @@ -51,6 +53,11 @@ _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) { @@ -347,6 +354,16 @@ _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)); } @@ -657,6 +674,178 @@ 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 7480eee867..fe9cbd9a5d 100644 --- a/src/lib/ecore/efl_loop.eo +++ b/src/lib/ecore/efl_loop.eo @@ -125,6 +125,8 @@ 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 311de0506a..6442669efd 100644 --- a/src/lib/ecore/efl_task.c +++ b/src/lib/ecore/efl_task.c @@ -227,6 +227,19 @@ _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 @@ -309,6 +322,34 @@ _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) { @@ -345,13 +386,32 @@ _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 EINA_UNUSED, Efl_Object *parent) +_efl_task_efl_object_parent_set(Eo *obj, Efl_Task_Data *pd, 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 526746ff60..92f0094fef 100644 --- a/src/lib/ecore/efl_task.eo +++ b/src/lib/ecore/efl_task.eo @@ -96,6 +96,26 @@ 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 { } diff --git a/src/lib/ecore/meson.build b/src/lib/ecore/meson.build index 98909cb618..baa5263698 100644 --- a/src/lib/ecore/meson.build +++ b/src/lib/ecore/meson.build @@ -74,9 +74,7 @@ pub_eo_files = [ 'efl_boolean_model.eo', 'efl_select_model.eo', 'efl_composite_model.eo', - 'efl_view_model.eo', - 'efl_core_env.eo', - 'efl_core_proc_env.eo' + 'efl_view_model.eo' ] foreach eo_file : pub_eo_files @@ -182,8 +180,6 @@ ecore_src = [ 'efl_thread.c', 'efl_threadio.c', 'efl_appthread.c', - 'efl_core_env.c', - 'efl_core_proc_env.c', ] if sys_windows == true diff --git a/src/tests/ecore/efl_app_suite.c b/src/tests/ecore/efl_app_suite.c index cd26e2d95e..b3be09915a 100644 --- a/src/tests/ecore/efl_app_suite.c +++ b/src/tests/ecore/efl_app_suite.c @@ -9,6 +9,7 @@ #include "efl_app_suite.h" #include "../efl_check.h" + EFL_START_TEST(efl_app_test_efl_build_version) { const Efl_Version *ver; @@ -52,7 +53,6 @@ static const Efl_Test_Case etc[] = { { "Promise", efl_app_test_promise_2 }, { "Promise", efl_app_test_promise_3 }, { "Promise", efl_app_test_promise_safety }, - { "Env", efl_test_efl_env }, { NULL, NULL } }; diff --git a/src/tests/ecore/efl_app_suite.h b/src/tests/ecore/efl_app_suite.h index 3a66dcdfcf..29ed8f031f 100644 --- a/src/tests/ecore/efl_app_suite.h +++ b/src/tests/ecore/efl_app_suite.h @@ -11,6 +11,5 @@ void efl_app_test_promise(TCase *tc); void efl_app_test_promise_2(TCase *tc); void efl_app_test_promise_3(TCase *tc); void efl_app_test_promise_safety(TCase *tc); -void efl_test_efl_env(TCase *tc); #endif /* _EFL_APP_SUITE_H */ diff --git a/src/tests/ecore/efl_app_test_env.c b/src/tests/ecore/efl_app_test_env.c deleted file mode 100644 index 63bad166a2..0000000000 --- a/src/tests/ecore/efl_app_test_env.c +++ /dev/null @@ -1,135 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#define EFL_NOLEGACY_API_SUPPORT -#include -#include "efl_app_suite.h" -#include "../efl_check.h" - -EFL_START_TEST(efl_core_env_test_set_get) -{ - Efl_Core_Env *env = efl_add_ref(EFL_CORE_ENV_CLASS, NULL); - - efl_core_env_set(env, "FOO", "bar"); - efl_core_env_set(env, "going", "home"); - efl_core_env_set(env, "Merry", "christmas"); - - ck_assert_str_eq(efl_core_env_get(env, "FOO"), "bar"); - ck_assert_str_eq(efl_core_env_get(env, "going"), "home"); - ck_assert_str_eq(efl_core_env_get(env, "Merry"), "christmas"); - - efl_core_env_unset(env, "Merry"); - - ck_assert_str_eq(efl_core_env_get(env, "FOO"), "bar"); - ck_assert_str_eq(efl_core_env_get(env, "going"), "home"); - ck_assert_ptr_eq(efl_core_env_get(env, "Merry"), NULL); - - efl_unref(env); -} -EFL_END_TEST - -EFL_START_TEST(efl_core_env_test_invalid_keys) -{ - Efl_Core_Env *env = efl_add_ref(EFL_CORE_ENV_CLASS, NULL); - -#define CHECK(val) \ - efl_core_env_set(env, val, "TEST"); \ - ck_assert_ptr_eq(efl_core_env_get(env, val), NULL); - - CHECK("0foo"); - CHECK("foo bar"); - CHECK("foo!bar"); - -#undef CHECK - - -#define CHECK(val) \ - efl_core_env_set(env, val, "TEST"); \ - ck_assert_str_eq(efl_core_env_get(env, val), "TEST"); - - CHECK("foo0"); - CHECK("foo_bar"); - -#undef CHECK - -} -EFL_END_TEST - -EFL_START_TEST(efl_core_env_test_clear) -{ - Efl_Core_Env *env = efl_add_ref(EFL_CORE_ENV_CLASS, NULL); - - efl_core_env_set(env, "FOO", "bar"); - efl_core_env_set(env, "going", "home"); - efl_core_env_set(env, "Merry", "christmas"); - - efl_core_env_clear(env); - - ck_assert_ptr_eq(efl_core_env_get(env, "FOO"), NULL); - ck_assert_ptr_eq(efl_core_env_get(env, "going"), NULL); - ck_assert_ptr_eq(efl_core_env_get(env, "Merry"), NULL); - - efl_unref(env); -} -EFL_END_TEST - -EFL_START_TEST(efl_core_env_test_fork) -{ - Efl_Core_Env *env_fork, *env = efl_add_ref(EFL_CORE_ENV_CLASS, NULL); - - efl_core_env_set(env, "FOO", "bar"); - efl_core_env_set(env, "going", "home"); - efl_core_env_set(env, "Merry", "christmas"); - - env_fork = efl_duplicate(env); - - ck_assert_str_eq(efl_core_env_get(env_fork, "FOO"), "bar"); - ck_assert_str_eq(efl_core_env_get(env_fork, "going"), "home"); - ck_assert_str_eq(efl_core_env_get(env_fork, "Merry"), "christmas"); - - efl_unref(env); -} -EFL_END_TEST - -EFL_START_TEST(efl_core_env_test_process) -{ - Efl_Core_Env *env_fork, *env = efl_env_self(EFL_CORE_PROC_ENV_CLASS); - - ck_assert(env); - - ck_assert_str_eq(efl_core_env_get(env, "PATH"), getenv("PATH")); - env_fork = efl_duplicate(env); - ck_assert_str_eq(efl_core_env_get(env_fork, "PATH"), getenv("PATH")); - - efl_unref(env); -} -EFL_END_TEST - -EFL_START_TEST(efl_core_env_test_undepend_fork) -{ - Efl_Core_Env *env_fork, *env = efl_env_self(EFL_CORE_PROC_ENV_CLASS); - - ck_assert(env); - - ck_assert_str_eq(efl_core_env_get(env, "PATH"), getenv("PATH")); - env_fork = efl_duplicate(env); - efl_core_env_set(env_fork, "PATH", "abc"); - ck_assert_str_eq(efl_core_env_get(env, "PATH"), getenv("PATH")); - - efl_unref(env); - efl_unref(env_fork); -} -EFL_END_TEST - -void efl_test_efl_env(TCase *tc) -{ - tcase_add_test(tc, efl_core_env_test_set_get); - tcase_add_test(tc, efl_core_env_test_invalid_keys); - tcase_add_test(tc, efl_core_env_test_clear); - tcase_add_test(tc, efl_core_env_test_fork); - tcase_add_test(tc, efl_core_env_test_process); - tcase_add_test(tc, efl_core_env_test_undepend_fork); -} diff --git a/src/tests/ecore/meson.build b/src/tests/ecore/meson.build index e3b4f6c851..4b46814bbe 100644 --- a/src/tests/ecore/meson.build +++ b/src/tests/ecore/meson.build @@ -75,8 +75,7 @@ efl_app_suite_src = [ 'efl_app_test_loop.c', 'efl_app_test_loop_fd.c', 'efl_app_test_loop_timer.c', - 'efl_app_test_promise.c', - 'efl_app_test_env.c' + 'efl_app_test_promise.c' ] efl_app_suite_deps = [m]