aboutsummaryrefslogtreecommitdiff
path: root/src/os/fs.c
diff options
context:
space:
mode:
authorThomas Wienecke <wienecke.t@gmail.com>2014-03-06 14:21:02 +0100
committerThiago de Arruda <tpadilha84@gmail.com>2014-03-07 17:30:39 -0300
commitd5b223afe22b0809e4718749a3cdc40ceb5434dd (patch)
tree3b3beded2b841e76251ca3e9d92e37b8ca84e27a /src/os/fs.c
parent1468c12fd1b649644eeacd447dbb0865eb0cdb43 (diff)
downloadrneovim-d5b223afe22b0809e4718749a3cdc40ceb5434dd.tar.gz
rneovim-d5b223afe22b0809e4718749a3cdc40ceb5434dd.tar.bz2
rneovim-d5b223afe22b0809e4718749a3cdc40ceb5434dd.zip
Move mch_can_exe, executable_file to os/fs.c.
* Rename executable_file to is_executable.
Diffstat (limited to 'src/os/fs.c')
-rw-r--r--src/os/fs.c88
1 files changed, 86 insertions, 2 deletions
diff --git a/src/os/fs.c b/src/os/fs.c
index 6ae48ab269..a1e3cd2899 100644
--- a/src/os/fs.c
+++ b/src/os/fs.c
@@ -15,6 +15,7 @@
#include "os.h"
#include "../message.h"
+#include "../misc1.h"
#include "../misc2.h"
int mch_chdir(char *path) {
@@ -40,7 +41,7 @@ int mch_dirname(char_u *buf, int len)
return OK;
}
-/*
+/*
* Get the absolute name of the given relative directory.
*
* parameter directory: Directory name, relative to current directory.
@@ -85,7 +86,7 @@ int mch_full_dir_name(char *directory, char *buffer, int len)
return retval;
}
-/*
+/*
* Append to_append to path with a slash in between.
*/
int append_path(char *path, char *to_append, int max_len)
@@ -191,3 +192,86 @@ int mch_isdir(char_u *name)
return TRUE;
}
+int is_executable(char_u *name);
+
+/*
+ * Return 1 if "name" is an executable file, 0 if not or it doesn't exist.
+ */
+int is_executable(char_u *name)
+{
+ uv_fs_t request;
+ if (0 != uv_fs_stat(uv_default_loop(), &request, (const char*) name, NULL)) {
+ return FALSE;
+ }
+
+ if (S_ISREG(request.statbuf.st_mode) &&
+ (S_IEXEC & request.statbuf.st_mode)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * Return 1 if "name" can be found in $PATH and executed, 0 if not.
+ * Return -1 if unknown.
+ */
+int mch_can_exe(char_u *name)
+{
+ char_u *buf;
+ char_u *path, *e;
+ int retval;
+
+ /* If it's an absolute or relative path don't need to use $PATH. */
+ if (mch_is_absolute_path(name) ||
+ (name[0] == '.' && (name[1] == '/' ||
+ (name[1] == '.' && name[2] == '/')))) {
+ return is_executable(name);
+ }
+
+ path = (char_u *)getenv("PATH");
+ /* PATH environment variable does not exist or is empty. */
+ if (path == NULL || *path == NUL) {
+ return -1;
+ }
+
+ int buf_len = STRLEN(name) + STRLEN(path) + 2;
+ buf = alloc((unsigned)(buf_len));
+ if (buf == NULL) {
+ return -1;
+ }
+
+ /*
+ * Walk through all entries in $PATH to check if "name" exists there and
+ * is an executable file.
+ */
+ for (;; ) {
+ e = (char_u *)strchr((char *)path, ':');
+ if (e == NULL) {
+ e = path + STRLEN(path);
+ }
+
+ if (e - path <= 1) { /* empty entry means current dir */
+ STRCPY(buf, "./");
+ } else {
+ vim_strncpy(buf, path, e - path);
+ add_pathsep(buf);
+ }
+
+ append_path((char *) buf, (char *) name, buf_len);
+
+ retval = is_executable(buf);
+ if (retval == OK) {
+ break;
+ }
+
+ if (*e != ':') {
+ break;
+ }
+
+ path = e + 1;
+ }
+
+ vim_free(buf);
+ return retval;
+}