Add fallback implementation for setenv()
authorMichael Paquier <michael@paquier.xyz>
Tue, 1 Jun 2021 00:27:25 +0000 (09:27 +0900)
committerMichael Paquier <michael@paquier.xyz>
Tue, 1 Jun 2021 00:27:25 +0000 (09:27 +0900)
This fixes the code compilation on Windows with MSVC and Kerberos, as
a missing implementation of setenv() causes a compilation failure of the
GSSAPI code.  This was only reproducible when building the code with
Kerberos, something that buildfarm animal hamerkop has fixed recently.

This issue only happens on 12 and 13, as this code has been introduced
in b0b39f7.  HEAD is already able to compile properly thanks to
7ca37fb0, and this commit is a minimal cherry-pick of it.

Thanks to Tom Lane for the discussion.

Discussion: https://postgr.es/m/YLDtm5WGjPxm6ua4@paquier.xyz
Backpatch-through: 12

configure
configure.in
src/include/pg_config.h.in
src/include/port.h
src/include/port/win32_port.h
src/port/setenv.c [new file with mode: 0644]
src/tools/msvc/Mkvcbuild.pm
src/tools/msvc/Solution.pm

index cbbaf77e3faafaf60ad098148500d6c8c282ed33..a774a7c7f1a05ab567cfc8ef3c2b5a9179403168 100755 (executable)
--- a/configure
+++ b/configure
@@ -15858,12 +15858,29 @@ case $host_os in
         # Windows uses a specialised env handler
         mingw*)
 
+$as_echo "#define HAVE_SETENV 1" >>confdefs.h
+
+
 $as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
 
+                ac_cv_func_setenv=yes
                 ac_cv_func_unsetenv=yes
                 ;;
         *)
-                ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv"
+                ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv"
+if test "x$ac_cv_func_setenv" = xyes; then :
+  $as_echo "#define HAVE_SETENV 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" setenv.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS setenv.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv"
 if test "x$ac_cv_func_unsetenv" = xyes; then :
   $as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
 
index 14a6be6748eb0281137d80982ce6fb6ba850a0a5..8a124a3817d7ec0ef9e2ac90bc920debdfd401d3 100644 (file)
@@ -1747,11 +1747,13 @@ fi
 case $host_os in
         # Windows uses a specialised env handler
         mingw*)
+                AC_DEFINE(HAVE_SETENV, 1, [Define to 1 because replacement version used.])
                 AC_DEFINE(HAVE_UNSETENV, 1, [Define to 1 because replacement version used.])
+                ac_cv_func_setenv=yes
                 ac_cv_func_unsetenv=yes
                 ;;
         *)
-                AC_REPLACE_FUNCS([unsetenv])
+                AC_REPLACE_FUNCS([setenv unsetenv])
                 ;;
 esac
 
index c199cd46d2da3da235577a6a966e7f3a42fb6f49..2fdf6ad2899fd0942ee7de7c56aa283a7350f941 100644 (file)
 /* Define to 1 if you have the <security/pam_appl.h> header file. */
 #undef HAVE_SECURITY_PAM_APPL_H
 
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
 /* Define to 1 if you have the `setproctitle' function. */
 #undef HAVE_SETPROCTITLE
 
index 271ff0d00bcce5ec2193060ba01d0a8f7704f9af..d4c94a4411d9effb7378a4d44c678cf526906f99 100644 (file)
@@ -429,6 +429,10 @@ extern size_t strnlen(const char *str, size_t maxlen);
 extern long random(void);
 #endif
 
+#ifndef HAVE_SETENV
+extern int setenv(const char *name, const char *value, int overwrite);
+#endif
+
 #ifndef HAVE_UNSETENV
 extern void unsetenv(const char *name);
 #endif
index 8b6576b23dc869dc3d4c5a9c0bc1fd38aea995b0..6c0f788ab418dcd14bffc116c080ec452fc9a8c8 100644 (file)
@@ -462,6 +462,7 @@ extern void _dosmaperr(unsigned long);
 
 /* in port/win32env.c */
 extern int pgwin32_putenv(const char *);
+extern int pgwin32_setenv(const char *name, const char *value, int overwrite);
 extern void pgwin32_unsetenv(const char *);
 
 /* in port/win32security.c */
@@ -472,6 +473,7 @@ extern int  pgwin32_is_admin(void);
 extern BOOL AddUserToTokenDacl(HANDLE hToken);
 
 #define putenv(x) pgwin32_putenv(x)
+#define setenv(x,y,z) pgwin32_setenv(x,y,z)
 #define unsetenv(x) pgwin32_unsetenv(x)
 
 /* Things that exist in MinGW headers, but need to be added to MSVC */
diff --git a/src/port/setenv.c b/src/port/setenv.c
new file mode 100644 (file)
index 0000000..440bc83
--- /dev/null
@@ -0,0 +1,48 @@
+/*-------------------------------------------------------------------------
+ *
+ * setenv.c
+ *   setenv() emulation for machines without it
+ *
+ * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *   src/port/setenv.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "c.h"
+
+
+int
+setenv(const char *name, const char *value, int overwrite)
+{
+   char       *envstr;
+
+   /* Error conditions, per POSIX */
+   if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL ||
+       value == NULL)
+   {
+       errno = EINVAL;
+       return -1;
+   }
+
+   /* No work if variable exists and we're not to replace it */
+   if (overwrite == 0 && getenv(name) != NULL)
+       return 0;
+
+   /*
+    * Add or replace the value using putenv().  This will leak memory if the
+    * same variable is repeatedly redefined, but there's little we can do
+    * about that when sitting atop putenv().
+    */
+   envstr = (char *) malloc(strlen(name) + strlen(value) + 2);
+   if (!envstr)                /* not much we can do if no memory */
+       return -1;
+
+   sprintf(envstr, "%s=%s", name, value);
+
+   return putenv(envstr);
+}
index 20da7985c10114f462d7ae0240e0bb90f0cfdc12..a8195a4930630df9f7e2fc7732ecbf167345db26 100644 (file)
@@ -101,7 +101,7 @@ sub mkvcbuild
      dirent.c dlopen.c getopt.c getopt_long.c link.c
      pread.c pwrite.c pg_bitutils.c
      pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c
-     pqsignal.c mkdtemp.c qsort.c qsort_arg.c quotes.c system.c
+     pqsignal.c mkdtemp.c qsort.c qsort_arg.c quotes.c setenv.c system.c
      sprompt.c strerror.c tar.c thread.c
      win32env.c win32error.c win32security.c win32setlocale.c);
 
index 38ddf09f65c722e4111419025fad07eec5eec579..7f533b5ccf5fec10885d2656045794f8577729a9 100644 (file)
@@ -341,6 +341,7 @@ sub GenerateFiles
        HAVE_RL_FILENAME_QUOTING_FUNCTION        => undef,
        HAVE_RL_RESET_SCREEN_SIZE                => undef,
        HAVE_SECURITY_PAM_APPL_H                 => undef,
+       HAVE_SETENV                              => undef,
        HAVE_SETPROCTITLE                        => undef,
        HAVE_SETPROCTITLE_FAST                   => undef,
        HAVE_SETSID                              => undef,