1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-18 14:17:03 +01:00

common,w32: Fix setting environment variables on Windows.

* common/sysutils.c (gnupg_setenv): Also update the environment block
maintained by the C runtime.
(gnupg_unsetenv): Likewise.
* tests/gpgscm/ffi.c (do_setenv): Fix error handling.

Signed-off-by: Justus Winter <justus@g10code.com>
This commit is contained in:
Justus Winter 2016-10-20 16:45:18 +02:00
parent bf37916a23
commit 8c7c4faf3d
2 changed files with 64 additions and 39 deletions

View File

@ -754,22 +754,32 @@ gnupg_setenv (const char *name, const char *value, int overwrite)
(void)value; (void)value;
(void)overwrite; (void)overwrite;
return 0; return 0;
#elif defined(HAVE_W32_SYSTEM) #else
if (!overwrite) #if defined(HAVE_W32_SYSTEM)
/* Windows maintains (at least) two sets of environment variables.
One set can be accessed by GetEnvironmentVariable and
SetEnvironmentVariable. This set is inherited by the children.
The other set is maintained in the C runtime, and is accessed
using getenv and putenv. We try to keep them in sync by
modifying both sets. */
{ {
int exists;
char tmpbuf[10]; char tmpbuf[10];
if (GetEnvironmentVariable (name, tmpbuf, sizeof tmpbuf)) exists = GetEnvironmentVariable (name, tmpbuf, sizeof tmpbuf);
return 0; /* Exists but overwrite was not requested. */
} if ((! exists || overwrite) && !SetEnvironmentVariable (name, value))
if (!SetEnvironmentVariable (name, value))
{ {
gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */ gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
return -1; return -1;
} }
return 0; }
#elif defined(HAVE_SETENV) #endif
#if defined(HAVE_SETENV)
return setenv (name, value, overwrite); return setenv (name, value, overwrite);
#else #else
if (! getenv (name) || overwrite)
{
char *buf; char *buf;
(void)overwrite; (void)overwrite;
@ -786,6 +796,9 @@ gnupg_setenv (const char *name, const char *value, int overwrite)
# warning no setenv - using putenv but leaking memory. # warning no setenv - using putenv but leaking memory.
#endif #endif
return putenv (buf); return putenv (buf);
}
return 0;
#endif
#endif #endif
} }
@ -796,16 +809,24 @@ gnupg_unsetenv (const char *name)
#ifdef HAVE_W32CE_SYSTEM #ifdef HAVE_W32CE_SYSTEM
(void)name; (void)name;
return 0; return 0;
#elif defined(HAVE_W32_SYSTEM) #else
#if defined(HAVE_W32_SYSTEM)
/* Windows maintains (at least) two sets of environment variables.
One set can be accessed by GetEnvironmentVariable and
SetEnvironmentVariable. This set is inherited by the children.
The other set is maintained in the C runtime, and is accessed
using getenv and putenv. We try to keep them in sync by
modifying both sets. */
if (!SetEnvironmentVariable (name, NULL)) if (!SetEnvironmentVariable (name, NULL))
{ {
gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */ gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
return -1; return -1;
} }
return 0; #endif
#elif defined(HAVE_UNSETENV) #if defined(HAVE_UNSETENV)
return unsetenv (name); return unsetenv (name);
#else #else
{
char *buf; char *buf;
if (!name) if (!name)
@ -820,6 +841,8 @@ gnupg_unsetenv (const char *name)
# warning no unsetenv - trying putenv but leaking memory. # warning no unsetenv - trying putenv but leaking memory.
#endif #endif
return putenv (buf); return putenv (buf);
}
#endif
#endif #endif
} }

View File

@ -236,7 +236,9 @@ do_setenv (scheme *sc, pointer args)
FFI_ARG_OR_RETURN (sc, char *, value, string, args); FFI_ARG_OR_RETURN (sc, char *, value, string, args);
FFI_ARG_OR_RETURN (sc, int, overwrite, bool, args); FFI_ARG_OR_RETURN (sc, int, overwrite, bool, args);
FFI_ARGS_DONE_OR_RETURN (sc, args); FFI_ARGS_DONE_OR_RETURN (sc, args);
FFI_RETURN_ERR (sc, gnupg_setenv (name, value, overwrite)); if (gnupg_setenv (name, value, overwrite))
FFI_RETURN_ERR (sc, gpg_error_from_syserror ());
FFI_RETURN (sc);
} }
static pointer static pointer