diff options
Diffstat (limited to 'src/nvim/os')
-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 |
4 files changed, 48 insertions, 6 deletions
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 |