[Pkg-gnupg-commit] [gnupg2] 138/292: common, w32: Fix setting environment variables on Windows.

Daniel Kahn Gillmor dkg at fifthhorseman.net
Mon Nov 21 06:31:34 UTC 2016


This is an automated email from the git hooks/post-receive script.

dkg pushed a commit to branch master
in repository gnupg2.

commit 8c7c4faf3de28ca70a60e6b15f51c1b206e0ddd9
Author: Justus Winter <justus at g10code.com>
Date:   Thu Oct 20 16:45:18 2016 +0200

    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 at g10code.com>
---
 common/sysutils.c  | 101 ++++++++++++++++++++++++++++++++---------------------
 tests/gpgscm/ffi.c |   4 ++-
 2 files changed, 65 insertions(+), 40 deletions(-)

diff --git a/common/sysutils.c b/common/sysutils.c
index 2e663bc..85eb203 100644
--- a/common/sysutils.c
+++ b/common/sysutils.c
@@ -754,38 +754,51 @@ gnupg_setenv (const char *name, const char *value, int overwrite)
   (void)value;
   (void)overwrite;
   return 0;
-#elif defined(HAVE_W32_SYSTEM)
-  if (!overwrite)
-    {
-      char tmpbuf[10];
-      if (GetEnvironmentVariable (name, tmpbuf, sizeof tmpbuf))
-        return 0; /* Exists but overwrite was not requested.  */
-    }
-  if (!SetEnvironmentVariable (name, value))
-    {
-      gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
-      return -1;
-    }
-  return 0;
-#elif defined(HAVE_SETENV)
-  return setenv (name, value, overwrite);
 #else
-  char *buf;
+#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];
+    exists = GetEnvironmentVariable (name, tmpbuf, sizeof tmpbuf);
+
+    if ((! exists || overwrite) && !SetEnvironmentVariable (name, value))
+      {
+        gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
+        return -1;
+      }
+  }
+#endif
 
-  (void)overwrite;
-  if (!name || !value)
+#if defined(HAVE_SETENV)
+  return setenv (name, value, overwrite);
+#else
+  if (! getenv (name) || overwrite)
     {
-      gpg_err_set_errno (EINVAL);
-      return -1;
-    }
-  buf = xtrymalloc (strlen (name) + 1 + strlen (value) + 1);
-  if (!buf)
-    return -1;
-  strcpy (stpcpy (stpcpy (buf, name), "="), value);
+      char *buf;
+
+      (void)overwrite;
+      if (!name || !value)
+        {
+          gpg_err_set_errno (EINVAL);
+          return -1;
+        }
+      buf = xtrymalloc (strlen (name) + 1 + strlen (value) + 1);
+      if (!buf)
+        return -1;
+      strcpy (stpcpy (stpcpy (buf, name), "="), value);
 #if __GNUC__
 # warning no setenv - using putenv but leaking memory.
 #endif
-  return putenv (buf);
+      return putenv (buf);
+    }
+  return 0;
+#endif
 #endif
 }
 
@@ -796,30 +809,40 @@ gnupg_unsetenv (const char *name)
 #ifdef HAVE_W32CE_SYSTEM
   (void)name;
   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))
     {
       gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
       return -1;
     }
-  return 0;
-#elif defined(HAVE_UNSETENV)
+#endif
+#if defined(HAVE_UNSETENV)
   return unsetenv (name);
 #else
-  char *buf;
-
-  if (!name)
-    {
-      gpg_err_set_errno (EINVAL);
+  {
+    char *buf;
+
+    if (!name)
+      {
+        gpg_err_set_errno (EINVAL);
+        return -1;
+      }
+    buf = xtrystrdup (name);
+    if (!buf)
       return -1;
-    }
-  buf = xtrystrdup (name);
-  if (!buf)
-    return -1;
 #if __GNUC__
 # warning no unsetenv - trying putenv but leaking memory.
 #endif
-  return putenv (buf);
+    return putenv (buf);
+  }
+#endif
 #endif
 }
 
diff --git a/tests/gpgscm/ffi.c b/tests/gpgscm/ffi.c
index a0fbe2e..8e21ba6 100644
--- a/tests/gpgscm/ffi.c
+++ b/tests/gpgscm/ffi.c
@@ -236,7 +236,9 @@ do_setenv (scheme *sc, pointer args)
   FFI_ARG_OR_RETURN (sc, char *, value, string, args);
   FFI_ARG_OR_RETURN (sc, int, overwrite, bool, 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

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git



More information about the Pkg-gnupg-commit mailing list