aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2017-02-01 02:25:40 +0100
committerJustin M. Keyes <justinkz@gmail.com>2017-02-04 11:07:49 +0100
commit8371d6fb0733d524b5357b210cd7a6728e71c50f (patch)
tree0df6886152dfbdf03ac9671bff7e894b811cfacf
parent3d3b1641d0cae3244c09d4602ab96d290dd0928a (diff)
downloadrneovim-8371d6fb0733d524b5357b210cd7a6728e71c50f.tar.gz
rneovim-8371d6fb0733d524b5357b210cd7a6728e71c50f.tar.bz2
rneovim-8371d6fb0733d524b5357b210cd7a6728e71c50f.zip
win: executable()
Windows: prepend `".;"` to PATH, as Vim does. https://github.com/vim/vim/blob/c4a249a736d40ec54794827ef95804c225d0e38f/src/os_win32.c#L1916
-rw-r--r--src/nvim/os/fs.c68
1 files changed, 38 insertions, 30 deletions
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 30e08ac129..b3d838c01a 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -223,11 +223,14 @@ bool os_can_exe(const char_u *name, char_u **abspath, bool use_path)
// need to use $PATH.
if (!use_path || path_is_absolute_path(name)
|| (name[0] == '.'
- && (name[1] == '/'
- || (name[1] == '.' && name[2] == '/')))) {
- // There must be a path separator, files in the current directory
- // can't be executed
- if (gettail_dir(name) != name && is_executable(name)) {
+ && (name[1] == '/' || (name[1] == '.' && name[2] == '/')))) {
+#if WIN32
+ bool ok = is_executable(name);
+#else
+ // Must have path separator, cannot execute files in the current directory.
+ bool ok = gettail_dir(name) != name && is_executable(name);
+#endif
+ if (ok) {
if (abspath != NULL) {
*abspath = save_absolute_path(name);
}
@@ -259,8 +262,6 @@ static bool is_executable(const char_u *name)
#else
return (S_ISREG(mode) && (S_IXUSR & mode));
#endif
-
- return false;
}
/// Checks if a file is inside the `$PATH` and is executable.
@@ -272,12 +273,21 @@ static bool is_executable(const char_u *name)
static bool is_executable_in_path(const char_u *name, char_u **abspath)
FUNC_ATTR_NONNULL_ARG(1)
{
- const char *path = os_getenv("PATH");
- if (path == NULL) {
+ const char *path_env = os_getenv("PATH");
+ if (path_env == NULL) {
return false;
}
- size_t buf_len = STRLEN(name) + STRLEN(path) + 2;
+#ifdef WIN32
+ // Prepend ".;" to $PATH.
+ size_t pathlen = strlen(path_env);
+ char *path = memcpy(xmallocz(pathlen + 3), ".;", 2);
+ memcpy(path + 2, path_env, pathlen);
+#else
+ char *path = xstrdup(path_env);
+#endif
+
+ size_t buf_len = STRLEN(name) + strlen(path) + 2;
#ifdef WIN32
const char *pathext = os_getenv("PATHEXT");
@@ -285,20 +295,21 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
pathext = ".com;.exe;.bat;.cmd";
}
- buf_len += STRLEN(pathext);
+ buf_len += strlen(pathext);
#endif
char_u *buf = xmalloc(buf_len);
// Walk through all entries in $PATH to check if "name" exists there and
// is an executable file.
+ char *p = path;
+ bool rv = false;
for (;; ) {
- const char *e = xstrchrnul(path, ENV_SEPCHAR);
+ char *e = xstrchrnul(p, ENV_SEPCHAR);
- // Glue together the given directory from $PATH with name and save into
- // buf.
- STRLCPY(buf, path, e - path + 1);
- append_path((char *) buf, (const char *) name, buf_len);
+ // Glue the directory from $PATH with `name` and save into buf.
+ STRLCPY(buf, p, e - p + 1);
+ append_path((char *)buf, (char *)name, buf_len);
if (is_executable(buf)) {
// Check if the caller asked for a copy of the path.
@@ -306,9 +317,8 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
*abspath = save_absolute_path(buf);
}
- xfree(buf);
-
- return true;
+ rv = true;
+ goto end;
}
#ifdef WIN32
@@ -316,9 +326,8 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
char *buf_end = xstrchrnul((char *)buf, '\0');
for (const char *ext = pathext; *ext; ext++) {
// Skip the extension if there is no suffix after a '.'.
- if (ext[0] == '.' && (ext[1] == '\0' || ext[1] == ';')) {
+ if (ext[0] == '.' && (ext[1] == '\0' || ext[1] == ENV_SEPCHAR)) {
*ext++;
-
continue;
}
@@ -331,9 +340,8 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
*abspath = save_absolute_path(buf);
}
- xfree(buf);
-
- return true;
+ rv = true;
+ goto end;
}
if (*ext_end != ENV_SEPCHAR) {
@@ -345,16 +353,16 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
if (*e != ENV_SEPCHAR) {
// End of $PATH without finding any executable called name.
- xfree(buf);
- return false;
+ goto end;
}
- path = e + 1;
+ p = e + 1;
}
- // We should never get to this point.
- assert(false);
- return false;
+end:
+ xfree(buf);
+ xfree(path);
+ return rv;
}
/// Opens or creates a file and returns a non-negative integer representing