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
This commit is contained in:
parent
2373d5db5b
commit
c3d69f66a6
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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 { }
|
||||
|
|
Loading…
Reference in New Issue