summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2021-06-01 09:27:25 +0900
committerMichael Paquier <michael@paquier.xyz>2021-06-01 09:27:25 +0900
commite2f21ff606dae2f7f7a9e323a88c99b464d2f787 (patch)
treec29f9d8101a001d6c977d3003e3cbfaa677b9830 /src
parentfe6f63286a00a49d0f82ac73fc252a3ad40d73b4 (diff)
Add fallback implementation for setenv()
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
Diffstat (limited to 'src')
-rw-r--r--src/include/pg_config.h.in3
-rw-r--r--src/include/port.h4
-rw-r--r--src/include/port/win32_port.h2
-rw-r--r--src/port/setenv.c48
-rw-r--r--src/tools/msvc/Mkvcbuild.pm2
-rw-r--r--src/tools/msvc/Solution.pm1
6 files changed, 59 insertions, 1 deletions
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index c199cd46d2d..2fdf6ad2899 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -473,6 +473,9 @@
/* 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
diff --git a/src/include/port.h b/src/include/port.h
index 271ff0d00bc..d4c94a4411d 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -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
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 8b6576b23dc..6c0f788ab41 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -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
index 00000000000..440bc832ce8
--- /dev/null
+++ b/src/port/setenv.c
@@ -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);
+}
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 20da7985c10..a8195a49306 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -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);
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 38ddf09f65c..7f533b5ccf5 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -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,