summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-02-01 13:14:16 +0100
committerBram Moolenaar <Bram@vim.org>2017-02-01 13:14:16 +0100
commit7c23d1d9d9cc1d3d19fe35708da7c5d5b3556e05 (patch)
tree74069459d85bf99f5b5048ff9f00511d13b0e058
parent168dd00f72515750505458018767f2ae0bcdb54e (diff)
patch 8.0.0280: problem setting multi-byte environment var on MS-Windowsv8.0.0280
Problem: On MS-Windows setting an environment variable with multi-byte strings does not work well. Solution: Use wputenv when possible. (Taro Muraoka, Ken Takata)
-rw-r--r--src/misc1.c3
-rw-r--r--src/os_win32.c57
-rw-r--r--src/os_win32.h4
-rw-r--r--src/proto/os_win32.pro1
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h1
6 files changed, 63 insertions, 5 deletions
diff --git a/src/misc1.c b/src/misc1.c
index cc5d5e60f6..f95c3fe477 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -4453,9 +4453,6 @@ vim_setenv(char_u *name, char_u *val)
{
sprintf((char *)envbuf, "%s=%s", name, val);
putenv((char *)envbuf);
-# ifdef libintl_putenv
- libintl_putenv((char *)envbuf);
-# endif
}
#endif
#ifdef FEAT_GETTEXT
diff --git a/src/os_win32.c b/src/os_win32.c
index 9b86478d3e..030b4b0da7 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -515,6 +515,7 @@ static char *null_libintl_textdomain(const char *);
static char *null_libintl_bindtextdomain(const char *, const char *);
static char *null_libintl_bind_textdomain_codeset(const char *, const char *);
static int null_libintl_putenv(const char *);
+static int null_libintl_wputenv(const wchar_t *);
static HINSTANCE hLibintlDLL = NULL;
char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext;
@@ -526,6 +527,7 @@ char *(*dyn_libintl_bindtextdomain)(const char *, const char *)
char *(*dyn_libintl_bind_textdomain_codeset)(const char *, const char *)
= null_libintl_bind_textdomain_codeset;
int (*dyn_libintl_putenv)(const char *) = null_libintl_putenv;
+int (*dyn_libintl_wputenv)(const wchar_t *) = null_libintl_wputenv;
int
dyn_libintl_init(void)
@@ -591,9 +593,14 @@ dyn_libintl_init(void)
/* _putenv() function for the libintl.dll is optional. */
hmsvcrt = find_imported_module_by_funcname(hLibintlDLL, "getenv");
if (hmsvcrt != NULL)
+ {
dyn_libintl_putenv = (void *)GetProcAddress(hmsvcrt, "_putenv");
- if (dyn_libintl_putenv == NULL || dyn_libintl_putenv == putenv)
+ dyn_libintl_wputenv = (void *)GetProcAddress(hmsvcrt, "_wputenv");
+ }
+ if (dyn_libintl_putenv == NULL || dyn_libintl_putenv == _putenv)
dyn_libintl_putenv = null_libintl_putenv;
+ if (dyn_libintl_wputenv == NULL || dyn_libintl_wputenv == _wputenv)
+ dyn_libintl_wputenv = null_libintl_wputenv;
return 1;
}
@@ -610,6 +617,7 @@ dyn_libintl_end(void)
dyn_libintl_bindtextdomain = null_libintl_bindtextdomain;
dyn_libintl_bind_textdomain_codeset = null_libintl_bind_textdomain_codeset;
dyn_libintl_putenv = null_libintl_putenv;
+ dyn_libintl_wputenv = null_libintl_wputenv;
}
/*ARGSUSED*/
@@ -658,6 +666,13 @@ null_libintl_putenv(const char *envstring)
return 0;
}
+/*ARGSUSED*/
+ int
+null_libintl_wputenv(const wchar_t *envstring)
+{
+ return 0;
+}
+
#endif /* DYNAMIC_GETTEXT */
/* This symbol is not defined in older versions of the SDK or Visual C++ */
@@ -6985,3 +7000,43 @@ fix_arg_enc(void)
set_alist_count();
}
#endif
+
+ int
+mch_setenv(char *var, char *value, int x)
+{
+ char_u *envbuf;
+
+ envbuf = alloc((unsigned)(STRLEN(var) + STRLEN(value) + 2));
+ if (envbuf == NULL)
+ return -1;
+
+ sprintf((char *)envbuf, "%s=%s", var, value);
+
+#ifdef FEAT_MBYTE
+ if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+ {
+ WCHAR *p = enc_to_utf16(envbuf, NULL);
+
+ vim_free(envbuf);
+ if (p == NULL)
+ return -1;
+ _wputenv(p);
+# ifdef libintl_wputenv
+ libintl_wputenv(p);
+# endif
+ /* Unlike Un*x systems, we can free the string for _wputenv(). */
+ vim_free(p);
+ }
+ else
+#endif
+ {
+ _putenv((char *)envbuf);
+# ifdef libintl_putenv
+ libintl_putenv((char *)envbuf);
+# endif
+ /* Unlike Un*x systems, we can free the string for _putenv(). */
+ vim_free(envbuf);
+ }
+
+ return 0;
+}
diff --git a/src/os_win32.h b/src/os_win32.h
index f620d742e8..5017f532ef 100644
--- a/src/os_win32.h
+++ b/src/os_win32.h
@@ -202,7 +202,9 @@ Trace(char *pszFormat, ...);
#define ASSERT_NULL_OR_POINTER(p, type) \
ASSERT(((p) == NULL) || IsValidAddress((p), sizeof(type), FALSE))
-#define mch_setenv(name, val, x) setenv(name, val, x)
+#ifndef HAVE_SETENV
+# define HAVE_SETENV
+#endif
#define mch_getenv(x) (char_u *)getenv((char *)(x))
#ifdef __BORLANDC__
# define vim_mkdir(x, y) mkdir(x)
diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro
index a64c863bbc..ca671464b9 100644
--- a/src/proto/os_win32.pro
+++ b/src/proto/os_win32.pro
@@ -65,4 +65,5 @@ void free_cmd_argsW(void);
void used_file_arg(char *name, int literal, int full_path, int diff_mode);
void set_alist_count(void);
void fix_arg_enc(void);
+int mch_setenv(char *var, char *value, int x);
/* vim: set ft=c : */
diff --git a/src/version.c b/src/version.c
index 82ee6d4e65..08e32cf90b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 280,
+/**/
279,
/**/
278,
diff --git a/src/vim.h b/src/vim.h
index abee386cb3..f3e87fef5c 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -594,6 +594,7 @@ extern int (*dyn_libintl_putenv)(const char *envstring);
# endif
# define textdomain(domain) (*dyn_libintl_textdomain)(domain)
# define libintl_putenv(envstring) (*dyn_libintl_putenv)(envstring)
+# define libintl_wputenv(envstring) (*dyn_libintl_wputenv)(envstring)
# else
# include <libintl.h>
# define _(x) gettext((char *)(x))