summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--header_checks/meson.build3
-rw-r--r--meson.build1
-rw-r--r--src/Makefile_Ecore.am7
-rw-r--r--src/lib/ecore/Ecore_Eo.h3
-rw-r--r--src/lib/ecore/ecore_private.h1
-rw-r--r--src/lib/ecore/efl_core_env.c2
-rw-r--r--src/lib/ecore/efl_core_env.eo57
-rw-r--r--src/lib/ecore/efl_core_proc_env.c145
-rw-r--r--src/lib/ecore/efl_core_proc_env.eo21
-rw-r--r--src/lib/ecore/efl_exe.c67
-rw-r--r--src/lib/ecore/efl_exe.eo17
-rw-r--r--src/lib/ecore/efl_loop.c189
-rw-r--r--src/lib/ecore/efl_loop.eo2
-rw-r--r--src/lib/ecore/efl_task.c62
-rw-r--r--src/lib/ecore/efl_task.eo20
-rw-r--r--src/lib/ecore/meson.build6
-rw-r--r--src/tests/ecore/efl_app_suite.c2
-rw-r--r--src/tests/ecore/efl_app_suite.h1
-rw-r--r--src/tests/ecore/efl_app_test_env.c135
-rw-r--r--src/tests/ecore/meson.build3
20 files changed, 305 insertions, 439 deletions
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<string>;
- }
- }
- }
- 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 <config.h>
-#endif
-
-#include <Ecore.h>
-#ifdef HAVE_CRT_EXTERNS_H
-# include <crt_externs.h>
-#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
@@ -310,6 +323,34 @@ _efl_task_arg_reset(Eo *obj EINA_UNUSED, Efl_Task_Data *pd)
}
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)
{
pd->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 <config.h>
-#endif
-
-#include <stdio.h>
-#include <unistd.h>
-#define EFL_NOLEGACY_API_SUPPORT
-#include <Efl_Core.h>
-#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]