diff options
| author | Justin M. Keyes <justinkz@gmail.com> | 2017-02-02 13:16:15 +0100 | 
|---|---|---|
| committer | Justin M. Keyes <justinkz@gmail.com> | 2017-02-04 11:07:49 +0100 | 
| commit | 224f99b85d311ebd31451db13b66e4a3c7e51938 (patch) | |
| tree | de2bb4bc8f06e09ede603ae535697384133a4ed5 /src | |
| parent | 7d58aba80c6d81a9af40f54e566c0cdcea2de3e3 (diff) | |
| download | rneovim-224f99b85d311ebd31451db13b66e4a3c7e51938.tar.gz rneovim-224f99b85d311ebd31451db13b66e4a3c7e51938.tar.bz2 rneovim-224f99b85d311ebd31451db13b66e4a3c7e51938.zip  | |
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
Diffstat (limited to 'src')
| -rw-r--r-- | src/nvim/main.c | 28 | ||||
| -rw-r--r-- | src/nvim/os/env.c | 40 | ||||
| -rw-r--r-- | src/nvim/os/fs.c | 8 | ||||
| -rw-r--r-- | src/nvim/os/unix_defs.h | 3 | ||||
| -rw-r--r-- | src/nvim/os/win_defs.h | 3 | 
5 files changed, 70 insertions, 12 deletions
diff --git a/src/nvim/main.c b/src/nvim/main.c index c7a60d07c1..6194e5f948 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -238,9 +238,7 @@ int main(int argc, char **argv)    // Check if we have an interactive window.    check_and_set_isatty(¶ms); -  // Get the name with which Nvim was invoked, with and without path. -  set_vim_var_string(VV_PROGPATH, argv[0], -1); -  set_vim_var_string(VV_PROGNAME, (char *) path_tail((char_u *) argv[0]), -1); +  init_path(argv[0]);    event_init();    /* @@ -1194,9 +1192,27 @@ static void check_and_set_isatty(mparm_T *paramp)    paramp->err_isatty = os_isatty(fileno(stderr));    TIME_MSG("window checked");  } -/* - * Get filename from command line, given that there is one. - */ + +// Sets v:progname and v:progpath. Also modifies $PATH on Windows. +static void init_path(char *exename) +{ +  char exepath[MAXPATHL] = { 0 }; +  size_t exepathlen = MAXPATHL; +  // Make v:progpath absolute. +  if (os_exepath(exepath, &exepathlen) != 0) { +    EMSG2(e_intern2, "init_path()"); +  } +  set_vim_var_string(VV_PROGPATH, exepath, -1); +  set_vim_var_string(VV_PROGNAME, (char *)path_tail((char_u *)exename), -1); + +#ifdef WIN32 +  // Append the process start directory to $PATH, so that ":!foo" finds tools +  // shipped with Windows package. This also mimics SearchPath(). +  os_setenv_append_path(exepath); +#endif +} + +/// Get filename from command line, if any.  static char_u *get_fname(mparm_T *parmp, char_u *cwd)  {  #if !defined(UNIX) 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; +} diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index b3d838c01a..4ca67d1f1a 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -224,7 +224,7 @@ bool os_can_exe(const char_u *name, char_u **abspath, bool use_path)    if (!use_path || path_is_absolute_path(name)        || (name[0] == '.'            && (name[1] == '/' || (name[1] == '.' && name[2] == '/')))) { -#if WIN32 +#ifdef WIN32      bool ok = is_executable(name);  #else      // Must have path separator, cannot execute files in the current directory. @@ -255,7 +255,7 @@ static bool is_executable(const char_u *name)      return false;    } -#if WIN32 +#ifdef WIN32    // Windows does not have exec bit; just check if the file exists and is not    // a directory.    return (S_ISREG(mode)); @@ -281,7 +281,7 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)  #ifdef WIN32    // Prepend ".;" to $PATH.    size_t pathlen = strlen(path_env); -  char *path = memcpy(xmallocz(pathlen + 3), ".;", 2); +  char *path = memcpy(xmallocz(pathlen + 3), "." ENV_SEPSTR, 2);    memcpy(path + 2, path_env, pathlen);  #else    char *path = xstrdup(path_env); @@ -1027,7 +1027,7 @@ shortcut_end:  int os_translate_sys_error(int sys_errno) {  #ifdef HAVE_UV_TRANSLATE_SYS_ERROR    return uv_translate_sys_error(sys_errno); -#elif WIN32 +#elif defined(WIN32)    // TODO(equalsraf): libuv does not yet expose uv_translate_sys_error()    // in its public API, include a version here until it can be used.    // See https://github.com/libuv/libuv/issues/79 diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h index 690a39c3cd..c98aa88bfa 100644 --- a/src/nvim/os/unix_defs.h +++ b/src/nvim/os/unix_defs.h @@ -16,7 +16,8 @@  // Special wildcards that need to be handled by the shell.  #define SPECIAL_WILDCHAR "`'{" -// Separator character for environment variables. +// Character that separates entries in $PATH.  #define ENV_SEPCHAR ':' +#define ENV_SEPSTR  ":"  #endif  // NVIM_OS_UNIX_DEFS_H diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h index 6a29f86e79..8de896c490 100644 --- a/src/nvim/os/win_defs.h +++ b/src/nvim/os/win_defs.h @@ -20,8 +20,9 @@  #define FNAME_ILLEGAL "\"*?><|" -// Separator character for environment variables. +// Character that separates entries in $PATH.  #define ENV_SEPCHAR ';' +#define ENV_SEPSTR  ";"  #define USE_CRNL  | 
