genviron: make g_environ_* case-insensitive on Windows

g_environ_getenv(env, "PATH") and g_environ_setenv(env, "PATH", newpath)
did not have the intended effect on Windows due to the environment block
containing "Path=". Make these functions case-insensitive for Windows.
This commit is contained in:
Peter Wu 2018-11-27 16:02:37 +01:00
parent 4f3216d7c0
commit a51ab0a5ab
2 changed files with 56 additions and 5 deletions

View File

@ -44,11 +44,24 @@
#include "gquark.h"
/* Environ array functions {{{1 */
static gboolean
g_environ_matches (const gchar *env, const gchar *variable, gsize len)
{
#ifdef G_OS_WIN32
/* TODO handle Unicode environment variable names */
/* Like filesystem paths, environment variables are case-insensitive. */
return g_ascii_strncasecmp (env, variable, len) == 0 && env[len] == '=';
#else
return strncmp (env, variable, len) == 0 && env[len] == '=';
#endif
}
static gint
g_environ_find (gchar **envp,
const gchar *variable)
{
gint len, i;
gsize len;
gint i;
if (envp == NULL)
return -1;
@ -57,8 +70,7 @@ g_environ_find (gchar **envp,
for (i = 0; envp[i]; i++)
{
if (strncmp (envp[i], variable, len) == 0 &&
envp[i][len] == '=')
if (g_environ_matches (envp[i], variable, len))
return i;
}
@ -155,7 +167,7 @@ g_environ_unsetenv_internal (gchar **envp,
const gchar *variable,
gboolean free_value)
{
gint len;
gsize len;
gchar **e, **f;
len = strlen (variable);
@ -166,7 +178,7 @@ g_environ_unsetenv_internal (gchar **envp,
e = f = envp;
while (*e != NULL)
{
if (strncmp (*e, variable, len) != 0 || (*e)[len] != '=')
if (!g_environ_matches (*e, variable, len))
{
*f = *e;
f++;

View File

@ -116,6 +116,44 @@ test_environ_null (void)
g_assert (env == NULL);
}
static void
test_environ_case (void)
{
gchar **env;
const gchar *value;
env = NULL;
env = g_environ_setenv (env, "foo", "bar", TRUE);
value = g_environ_getenv (env, "foo");
g_assert_cmpstr (value, ==, "bar");
value = g_environ_getenv (env, "Foo");
#ifdef G_OS_WIN32
g_assert_cmpstr (value, ==, "bar");
#else
g_assert (value == NULL);
#endif
env = g_environ_setenv (env, "FOO", "x", TRUE);
value = g_environ_getenv (env, "foo");
#ifdef G_OS_WIN32
g_assert_cmpstr (value, ==, "x");
#else
g_assert_cmpstr (value, ==, "bar");
#endif
env = g_environ_unsetenv (env, "Foo");
value = g_environ_getenv (env, "foo");
#ifdef G_OS_WIN32
g_assert (value == NULL);
#else
g_assert_cmpstr (value, ==, "bar");
#endif
g_strfreev (env);
}
int
main (int argc, char **argv)
{
@ -125,6 +163,7 @@ main (int argc, char **argv)
g_test_add_func ("/environ/setenv", test_setenv);
g_test_add_func ("/environ/array", test_environ_array);
g_test_add_func ("/environ/null", test_environ_null);
g_test_add_func ("/environ/case", test_environ_case);
return g_test_run ();
}