1
0
forked from aniani/vim

patch 8.0.0280: problem setting multi-byte environment var on MS-Windows

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)
This commit is contained in:
Bram Moolenaar
2017-02-01 13:14:16 +01:00
parent 168dd00f72
commit 7c23d1d9d9
6 changed files with 63 additions and 5 deletions

View File

@@ -4453,9 +4453,6 @@ vim_setenv(char_u *name, char_u *val)
{ {
sprintf((char *)envbuf, "%s=%s", name, val); sprintf((char *)envbuf, "%s=%s", name, val);
putenv((char *)envbuf); putenv((char *)envbuf);
# ifdef libintl_putenv
libintl_putenv((char *)envbuf);
# endif
} }
#endif #endif
#ifdef FEAT_GETTEXT #ifdef FEAT_GETTEXT

View File

@@ -515,6 +515,7 @@ static char *null_libintl_textdomain(const char *);
static char *null_libintl_bindtextdomain(const char *, const char *); static char *null_libintl_bindtextdomain(const char *, const char *);
static char *null_libintl_bind_textdomain_codeset(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_putenv(const char *);
static int null_libintl_wputenv(const wchar_t *);
static HINSTANCE hLibintlDLL = NULL; static HINSTANCE hLibintlDLL = NULL;
char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext; 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 *) char *(*dyn_libintl_bind_textdomain_codeset)(const char *, const char *)
= null_libintl_bind_textdomain_codeset; = null_libintl_bind_textdomain_codeset;
int (*dyn_libintl_putenv)(const char *) = null_libintl_putenv; int (*dyn_libintl_putenv)(const char *) = null_libintl_putenv;
int (*dyn_libintl_wputenv)(const wchar_t *) = null_libintl_wputenv;
int int
dyn_libintl_init(void) dyn_libintl_init(void)
@@ -591,9 +593,14 @@ dyn_libintl_init(void)
/* _putenv() function for the libintl.dll is optional. */ /* _putenv() function for the libintl.dll is optional. */
hmsvcrt = find_imported_module_by_funcname(hLibintlDLL, "getenv"); hmsvcrt = find_imported_module_by_funcname(hLibintlDLL, "getenv");
if (hmsvcrt != NULL) if (hmsvcrt != NULL)
{
dyn_libintl_putenv = (void *)GetProcAddress(hmsvcrt, "_putenv"); 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; dyn_libintl_putenv = null_libintl_putenv;
if (dyn_libintl_wputenv == NULL || dyn_libintl_wputenv == _wputenv)
dyn_libintl_wputenv = null_libintl_wputenv;
return 1; return 1;
} }
@@ -610,6 +617,7 @@ dyn_libintl_end(void)
dyn_libintl_bindtextdomain = null_libintl_bindtextdomain; dyn_libintl_bindtextdomain = null_libintl_bindtextdomain;
dyn_libintl_bind_textdomain_codeset = null_libintl_bind_textdomain_codeset; dyn_libintl_bind_textdomain_codeset = null_libintl_bind_textdomain_codeset;
dyn_libintl_putenv = null_libintl_putenv; dyn_libintl_putenv = null_libintl_putenv;
dyn_libintl_wputenv = null_libintl_wputenv;
} }
/*ARGSUSED*/ /*ARGSUSED*/
@@ -658,6 +666,13 @@ null_libintl_putenv(const char *envstring)
return 0; return 0;
} }
/*ARGSUSED*/
int
null_libintl_wputenv(const wchar_t *envstring)
{
return 0;
}
#endif /* DYNAMIC_GETTEXT */ #endif /* DYNAMIC_GETTEXT */
/* This symbol is not defined in older versions of the SDK or Visual C++ */ /* 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(); set_alist_count();
} }
#endif #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;
}

View File

@@ -202,7 +202,9 @@ Trace(char *pszFormat, ...);
#define ASSERT_NULL_OR_POINTER(p, type) \ #define ASSERT_NULL_OR_POINTER(p, type) \
ASSERT(((p) == NULL) || IsValidAddress((p), sizeof(type), FALSE)) 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)) #define mch_getenv(x) (char_u *)getenv((char *)(x))
#ifdef __BORLANDC__ #ifdef __BORLANDC__
# define vim_mkdir(x, y) mkdir(x) # define vim_mkdir(x, y) mkdir(x)

View File

@@ -65,4 +65,5 @@ void free_cmd_argsW(void);
void used_file_arg(char *name, int literal, int full_path, int diff_mode); void used_file_arg(char *name, int literal, int full_path, int diff_mode);
void set_alist_count(void); void set_alist_count(void);
void fix_arg_enc(void); void fix_arg_enc(void);
int mch_setenv(char *var, char *value, int x);
/* vim: set ft=c : */ /* vim: set ft=c : */

View File

@@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
280,
/**/ /**/
279, 279,
/**/ /**/

View File

@@ -594,6 +594,7 @@ extern int (*dyn_libintl_putenv)(const char *envstring);
# endif # endif
# define textdomain(domain) (*dyn_libintl_textdomain)(domain) # define textdomain(domain) (*dyn_libintl_textdomain)(domain)
# define libintl_putenv(envstring) (*dyn_libintl_putenv)(envstring) # define libintl_putenv(envstring) (*dyn_libintl_putenv)(envstring)
# define libintl_wputenv(envstring) (*dyn_libintl_wputenv)(envstring)
# else # else
# include <libintl.h> # include <libintl.h>
# define _(x) gettext((char *)(x)) # define _(x) gettext((char *)(x))