efl/src/lib/ecore/efl_core_proc_env.c

172 lines
3.9 KiB
C

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef _WIN32
# include <evil_private.h> /* setenv unsetenv */
#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
#if defined (__FreeBSD__) || defined (__OpenBSD__)
# include <dlfcn.h>
static char ***_dl_environ;
#else
extern char **environ;
#endif
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;
char **loc_env = NULL;
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 defined (__FreeBSD__) || defined (__OpenBSD__)
_dl_environ = dlsym(NULL, "environ");
if (_dl_environ) loc_env = *_dl_environ;
else ERR("Can't find envrion symbol");
#else
loc_env = environ;
#endif
if (loc_env)
{
char **p;
for (p = loc_env; *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
# if defined (__FreeBSD__) || defined (__OpenBSD__)
_dl_environ = dlsym(NULL, "environ");
if (_dl_environ) *_dl_environ = NULL;
else ERR("Can't find envrion symbol");
# else
environ = NULL;
# endif
#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(void)
{
if (!env)
{
efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
env = efl_add_ref(EFL_CORE_PROC_ENV_CLASS, NULL);
efl_domain_current_pop();
efl_wref_add(env, &env);
}
return env;
}
#include "efl_core_proc_env.eo.c"