From 224f99b85d311ebd31451db13b66e4a3c7e51938 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 2 Feb 2017 13:16:15 +0100 Subject: win: Append process dir to $PATH This allows executables to be found by :!, system(), and executable() if they live next to ("sibling" to) nvim.exe. This is what gvim on Windows does, and also matches the behavior of Win32 SearchPath(). https://github.com/vim/vim/blob/c4a249a736d40ec54794827ef95804c225d0e38f/src/os_win32.c#L354-L370 --- src/nvim/os/env.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'src/nvim/os/env.c') diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 747a34d8ce..4707b0a326 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -831,3 +831,43 @@ char_u *get_env_name(expand_T *xp, int idx) return NULL; } +/// Appends the head of `fname` to $PATH and sets it in the environment. +/// +/// @param fname Full path whose parent directory will be appended to $PATH. +/// +/// @return true if `path` was appended-to +bool os_setenv_append_path(const char *fname) + FUNC_ATTR_NONNULL_ALL +{ +#ifdef WIN32 +// 8191 (plus NUL) is considered the practical maximum. +# define MAX_ENVPATHLEN 8192 +#else +// No prescribed maximum on unix. +# define MAX_ENVPATHLEN INT_MAX +#endif + if (!path_is_absolute_path((char_u *)fname)) { + EMSG2(_(e_intern2), "os_setenv_append_path()"); + return false; + } + const char *tail = (char *)path_tail_with_sep((char_u *)fname); + const char *dir = (char *)vim_strnsave((char_u *)fname, + (size_t)(tail - fname)); + const char *path = os_getenv("PATH"); + const size_t pathlen = path ? strlen(path) : 0; + const size_t newlen = pathlen + strlen(dir) + 2; + if (newlen < MAX_ENVPATHLEN) { + char *temp = xmalloc(newlen); + if (pathlen == 0) { + temp[0] = NUL; + } else { + xstrlcpy(temp, path, newlen); + xstrlcat(temp, ENV_SEPSTR, newlen); + } + xstrlcat(temp, dir, newlen); + os_setenv("PATH", temp, 1); + xfree(temp); + return true; + } + return false; +} -- cgit From cd5b1315757ed3c66aa63c6df69582503c5b81dd Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 3 Feb 2017 14:42:47 +0100 Subject: vim-patch:8.0.0280 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) 7c23d1d9d9cc --- src/nvim/os/env.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/nvim/os/env.c') diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 4707b0a326..5a3c1ef2c8 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -9,6 +9,7 @@ #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/charset.h" +#include "nvim/fileio.h" #include "nvim/os/os.h" #include "nvim/memory.h" #include "nvim/message.h" @@ -18,6 +19,10 @@ #include "nvim/ex_getln.h" #include "nvim/version.h" +#ifdef WIN32 +#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 +#endif + #ifdef HAVE__NSGETENVIRON #include #endif @@ -45,7 +50,21 @@ bool os_env_exists(const char *name) int os_setenv(const char *name, const char *value, int overwrite) FUNC_ATTR_NONNULL_ALL { -#ifdef HAVE_SETENV +#ifdef WIN32 + size_t envbuflen = strlen(name) + strlen(value) + 2; + char *envbuf = xmalloc(envbuflen); + snprintf(envbuf, envbuflen, "%s=%s", name, value); + + WCHAR *p; + utf8_to_utf16(envbuf, &p); + xfree(envbuf); + if (p == NULL) { + return -1; + } + _wputenv(p); + xfree(p); // Unlike Unix systems, we can free the string for _wputenv(). + return 0; +#elif defined(HAVE_SETENV) return setenv(name, value, overwrite); #elif defined(HAVE_PUTENV_S) if (!overwrite && os_getenv(name) != NULL) { -- cgit