]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
add openconnect__win32_setenv function to compat.c
authorDaniel Lenski <dlenski@gmail.com>
Fri, 22 Jan 2021 02:01:42 +0000 (18:01 -0800)
committerDaniel Lenski <dlenski@gmail.com>
Sat, 23 Jan 2021 00:48:55 +0000 (16:48 -0800)
Based on:

* POSIX-compatible `setenv` implementation for Windows: https://stackoverflow.com/a/23616164
* Enabling Windows "secure API" getenv_s and _putenv_s functions in MinGW:
  * Using -DMINGW_HAS_SECURE_API: https://stackoverflow.com/a/51977723
  * By manually defining their prototypes: https://stackoverflow.com/a/51977723
  * Apparently, only newer versions of MinGW follow the MINGW_HAS_SECURE_API flag, and
    autodetecting them is quite hard.

Signed-off-by: Daniel Lenski <dlenski@gmail.com>
compat.c
openconnect-internal.h

index 1246730b8f0d64d542069817ea3f5897b5c488cb..ce5a703865db2922af0410f0e9fd5e024dc0d8a1 100644 (file)
--- a/compat.c
+++ b/compat.c
 
 #include <string.h>
 #include <stdarg.h>
+#ifdef _WIN32
+#include <sec_api/stdlib_s.h> /* errno_t, size_t */
+errno_t getenv_s(
+    size_t     *ret_required_buf_size,
+    char       *buf,
+    size_t      buf_size_in_bytes,
+    const char *name
+);
+errno_t _putenv_s(
+   const char *varname,
+   const char *value_string
+);
+
+/* XX: needed to get _putenv_s, getenv_s from stdlib.h with MinGW,
+ * but only works on newer versions.
+ * https://stackoverflow.com/a/51977723
+ */
+/* #define MINGW_HAS_SECURE_API 1 */
+#endif
 #include <stdlib.h>
 #include <errno.h>
 #include <ctype.h>
@@ -196,6 +215,18 @@ int openconnect__inet_aton(const char *cp, struct in_addr *addr)
 #endif
 
 #ifdef _WIN32
+int openconnect__win32_setenv(const char *name, const char *value, int overwrite)
+{
+       /* https://stackoverflow.com/a/23616164 */
+       int errcode = 0;
+       if(!overwrite) {
+               size_t envsize = 0;
+               errcode = getenv_s(&envsize, NULL, 0, name);
+               if(errcode || envsize) return errcode;
+       }
+       return _putenv_s(name, value);
+}
+
 char *openconnect__win32_strerror(DWORD err)
 {
        wchar_t *msgw;
index af11c36641418dc6dc51e141e86df64ddbf62620..d35bf4455d215fc4e39e6cb117a1cf1504c4d961 100644 (file)
@@ -825,6 +825,9 @@ static inline int tun_is_up(struct openconnect_info *vpninfo)
 #define pipe(fds) _pipe(fds, 4096, O_BINARY)
 int openconnect__win32_sock_init();
 char *openconnect__win32_strerror(DWORD err);
+#undef setenv
+#define setenv openconnect__win32_setenv
+int openconnect__win32_setenv(const char *name, const char *value, int overwrite);
 #undef inet_pton
 #define inet_pton openconnect__win32_inet_pton
 int openconnect__win32_inet_pton(int af, const char *src, void *dst);