Revert the env object because it's broken portability - please redo

setenv and unsetenv are not portable. i explained to you at fosdem
there are issues and it's why i used putenv in the original
implementation and even though it's a pain (the string tou pass to
putenv is a pointer used literallt from there on in and you get it
from getenv, thus making ownership a pain -this is a libc issue we
can't readily solve). use putenv like the original code. then put it
back in. vtorri now has windows porting issues with the setenv use. i
knew there was a reason that still existed...

in addition your in_sync stuff is broken.  psuedocode:

// assuming BLAGH env is not set to anything here
c = efl_core_env_get(global_env, "BLAH");
...
putenv("BLAH=10");
...
c = efl_core_env_Get(global_env, "BLAH");

i will get NULL in both cases for c ... but i should get "10" for the
2nd in reality. reality is lots of code across application code and
libraries will at times mess with the environment. it has to work with
this. the prior implementation did work with this.

Revert "ecore: here comes a env object"
  This reverts commit 2373d5db5b.

Revert "efl_task: remove env from this object"
  This reverts commit c3d69f66a6.
This commit is contained in:
Carsten Haitzler 2019-02-12 20:11:44 +00:00
parent a57c7f7510
commit d6294fa22b
20 changed files with 305 additions and 439 deletions

View File

@ -53,8 +53,7 @@ header_checks = [
'langinfo.h',
'locale.h',
'uv.h',
'ws2tcpip.h',
'crt_externs.h'
'ws2tcpip.h'
]
function_checks = [

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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"

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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);
}
}
}
//////////////////////////////////////////////////////////////////////////

View File

@ -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 { }

View File

@ -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

View File

@ -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 }
};

View File

@ -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 */

View File

@ -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);
}

View File

@ -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]