mirror of
https://github.com/neovim/neovim.git
synced 2025-09-29 14:38:32 +00:00
Move exe functions back to os/fs.c
This commit is contained in:

committed by
Thiago de Arruda

parent
6fb58d1c5c
commit
ac62041138
@@ -8562,7 +8562,7 @@ static void f_eventhandler(typval_T *argvars, typval_T *rettv)
|
||||
*/
|
||||
static void f_executable(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
rettv->vval.v_number = path_can_exe(get_tv_string(&argvars[0]));
|
||||
rettv->vval.v_number = os_can_exe(get_tv_string(&argvars[0]));
|
||||
}
|
||||
|
||||
/*
|
||||
|
80
src/os/fs.c
80
src/os/fs.c
@@ -7,6 +7,9 @@
|
||||
#include "misc2.h"
|
||||
#include "path.h"
|
||||
|
||||
static bool is_executable(const char_u *name);
|
||||
static bool is_executable_in_path(const char_u *name);
|
||||
|
||||
// Many fs functions from libuv return that value on success.
|
||||
static const int kLibuvSuccess = 0;
|
||||
|
||||
@@ -45,6 +48,82 @@ bool os_isdir(const char_u *name)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool os_can_exe(const char_u *name)
|
||||
{
|
||||
// If it's an absolute or relative path don't need to use $PATH.
|
||||
if (path_is_absolute_path(name) ||
|
||||
(name[0] == '.' && (name[1] == '/' ||
|
||||
(name[1] == '.' && name[2] == '/')))) {
|
||||
return is_executable(name);
|
||||
}
|
||||
|
||||
return is_executable_in_path(name);
|
||||
}
|
||||
|
||||
// Return true if "name" is an executable file, false if not or it doesn't
|
||||
// exist.
|
||||
static bool is_executable(const char_u *name)
|
||||
{
|
||||
int32_t mode = os_getperm(name);
|
||||
|
||||
if (mode < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (S_ISREG(mode) && (S_IEXEC & mode)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Check if a file is inside the $PATH and is executable.
|
||||
///
|
||||
/// @return `true` if `name` is an executable inside $PATH.
|
||||
static bool is_executable_in_path(const char_u *name)
|
||||
{
|
||||
const char *path = getenv("PATH");
|
||||
// PATH environment variable does not exist or is empty.
|
||||
if (path == NULL || *path == NUL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int buf_len = STRLEN(name) + STRLEN(path) + 2;
|
||||
char_u *buf = alloc((unsigned)(buf_len));
|
||||
|
||||
// Walk through all entries in $PATH to check if "name" exists there and
|
||||
// is an executable file.
|
||||
for (;; ) {
|
||||
const char *e = strchr(path, ':');
|
||||
if (e == NULL) {
|
||||
e = path + STRLEN(path);
|
||||
}
|
||||
|
||||
// Glue together the given directory from $PATH with name and save into
|
||||
// buf.
|
||||
vim_strncpy(buf, (char_u *) path, e - path);
|
||||
append_path((char *) buf, (const char *) name, buf_len);
|
||||
|
||||
if (is_executable(buf)) {
|
||||
// Found our executable. Free buf and return.
|
||||
vim_free(buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (*e != ':') {
|
||||
// End of $PATH without finding any executable called name.
|
||||
vim_free(buf);
|
||||
return false;
|
||||
}
|
||||
|
||||
path = e + 1;
|
||||
}
|
||||
|
||||
// We should never get to this point.
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
int os_stat(const char_u *name, uv_stat_t *statbuf)
|
||||
{
|
||||
uv_fs_t request;
|
||||
@@ -123,4 +202,3 @@ int os_rename(const char_u *path, const char_u *new_path)
|
||||
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
|
10
src/os/os.h
10
src/os/os.h
@@ -21,6 +21,16 @@ int os_dirname(char_u *buf, size_t len);
|
||||
/// @return `true` if `fname` is a directory.
|
||||
bool os_isdir(const char_u *name);
|
||||
|
||||
/// Check if the given path represents an executable file.
|
||||
///
|
||||
/// @return `true` if `name` is executable and
|
||||
/// - can be found in $PATH,
|
||||
/// - is relative to current dir or
|
||||
/// - is absolute.
|
||||
///
|
||||
/// @return `false` otherwise.
|
||||
bool os_can_exe(const char_u *name);
|
||||
|
||||
/// Get the file permissions for a given file.
|
||||
///
|
||||
/// @return `-1` when `name` doesn't exist.
|
||||
|
@@ -1418,7 +1418,7 @@ int flags; /* EW_* flags */
|
||||
continue;
|
||||
|
||||
/* Skip files that are not executable if we check for that. */
|
||||
if (!dir && (flags & EW_EXEC) && !path_can_exe((*file)[i]))
|
||||
if (!dir && (flags & EW_EXEC) && !os_can_exe((*file)[i]))
|
||||
continue;
|
||||
|
||||
p = alloc((unsigned)(STRLEN((*file)[i]) + 1 + dir));
|
||||
|
87
src/path.c
87
src/path.c
@@ -30,9 +30,7 @@
|
||||
#define URL_SLASH 1 /* path_is_url() has found "://" */
|
||||
#define URL_BACKSLASH 2 /* path_is_url() has found ":\\" */
|
||||
|
||||
static int os_get_absolute_path(char_u *fname, char_u *buf, int len, int force);
|
||||
static bool is_executable(const char_u *name);
|
||||
static bool is_executable_in_path(const char_u *name);
|
||||
static int path_get_absolute_path(char_u *fname, char_u *buf, int len, int force);
|
||||
|
||||
FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname)
|
||||
{
|
||||
@@ -1229,7 +1227,7 @@ addfile (
|
||||
return;
|
||||
|
||||
/* If the file isn't executable, may not add it. Do accept directories. */
|
||||
if (!isdir && (flags & EW_EXEC) && !path_can_exe(f))
|
||||
if (!isdir && (flags & EW_EXEC) && !os_can_exe(f))
|
||||
return;
|
||||
|
||||
/* Make room for another item in the file list. */
|
||||
@@ -1943,10 +1941,6 @@ int match_suffix(char_u *fname)
|
||||
return setsuflen != 0;
|
||||
}
|
||||
|
||||
/// Get the absolute name of the given relative directory.
|
||||
///
|
||||
/// @param directory Directory name, relative to current directory.
|
||||
/// @return `FAIL` for failure, `OK` for success.
|
||||
int path_full_dir_name(char *directory, char *buffer, int len)
|
||||
{
|
||||
int SUCCESS = 0;
|
||||
@@ -2061,80 +2055,3 @@ int path_is_absolute_path(const char_u *fname)
|
||||
{
|
||||
return *fname == '/' || *fname == '~';
|
||||
}
|
||||
|
||||
bool os_can_exe(const char_u *name)
|
||||
{
|
||||
// If it's an absolute or relative path don't need to use $PATH.
|
||||
if (path_is_absolute_path(name) ||
|
||||
(name[0] == '.' && (name[1] == '/' ||
|
||||
(name[1] == '.' && name[2] == '/')))) {
|
||||
return is_executable(name);
|
||||
}
|
||||
|
||||
return is_executable_in_path(name);
|
||||
}
|
||||
|
||||
// Return true if "name" is an executable file, false if not or it doesn't
|
||||
// exist.
|
||||
static bool is_executable(const char_u *name)
|
||||
{
|
||||
int32_t mode = os_getperm(name);
|
||||
|
||||
if (mode < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (S_ISREG(mode) && (S_IEXEC & mode)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Check if a file is inside the $PATH and is executable.
|
||||
///
|
||||
/// @return `true` if `name` is an executable inside $PATH.
|
||||
static bool is_executable_in_path(const char_u *name)
|
||||
{
|
||||
const char *path = getenv("PATH");
|
||||
// PATH environment variable does not exist or is empty.
|
||||
if (path == NULL || *path == NUL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int buf_len = STRLEN(name) + STRLEN(path) + 2;
|
||||
char_u *buf = alloc((unsigned)(buf_len));
|
||||
|
||||
// Walk through all entries in $PATH to check if "name" exists there and
|
||||
// is an executable file.
|
||||
for (;; ) {
|
||||
const char *e = strchr(path, ':');
|
||||
if (e == NULL) {
|
||||
e = path + STRLEN(path);
|
||||
}
|
||||
|
||||
// Glue together the given directory from $PATH with name and save into
|
||||
// buf.
|
||||
vim_strncpy(buf, (char_u *) path, e - path);
|
||||
append_path((char *) buf, (const char *) name, buf_len);
|
||||
|
||||
if (is_executable(buf)) {
|
||||
// Found our executable. Free buf and return.
|
||||
vim_free(buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (*e != ':') {
|
||||
// End of $PATH without finding any executable called name.
|
||||
vim_free(buf);
|
||||
return false;
|
||||
}
|
||||
|
||||
path = e + 1;
|
||||
}
|
||||
|
||||
// We should never get to this point.
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
10
src/path.h
10
src/path.h
@@ -103,14 +103,4 @@ int append_path(char *path, const char *to_append, int max_len);
|
||||
/// @return `TRUE` if "fname" is absolute.
|
||||
int path_is_absolute_path(const char_u *fname);
|
||||
|
||||
/// Check if the given path represents an executable file.
|
||||
///
|
||||
/// @return `TRUE` if `name` is executable and
|
||||
/// - can be found in $PATH,
|
||||
/// - is relative to current dir or
|
||||
/// - is absolute.
|
||||
///
|
||||
/// @return `FALSE` otherwise.
|
||||
int path_can_exe(const char_u *name);
|
||||
|
||||
#endif
|
||||
|
@@ -11,16 +11,12 @@ FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname);
|
||||
char_u *path_tail(char_u *fname);
|
||||
char_u *path_tail_with_sep(char_u *fname);
|
||||
char_u *path_next_component(char_u *fname);
|
||||
int is_executable(char_u *name);
|
||||
int path_can_exe(char_u *name);
|
||||
]]
|
||||
|
||||
|
||||
-- import constants parsed by ffi
|
||||
{:kEqualFiles, :kDifferentFiles, :kBothFilesMissing, :kOneFileMissing, :kEqualFileNames} = path
|
||||
NULL = ffi.cast 'void*', 0
|
||||
{:OK, :FAIL} = path
|
||||
{:TRUE, :FALSE} = path
|
||||
|
||||
describe 'path function', ->
|
||||
describe 'path_full_compare', ->
|
||||
@@ -264,26 +260,3 @@ describe 'more path function', ->
|
||||
|
||||
it 'returns false if filename starts not with slash nor tilde', ->
|
||||
eq FAIL, path_is_absolute_path 'not/in/my/home~/directory'
|
||||
|
||||
describe 'path_can_exe', ->
|
||||
path_can_exe = (name) ->
|
||||
path.path_can_exe (to_cstr name)
|
||||
|
||||
it 'returns false when given a directory', ->
|
||||
eq FALSE, (path_can_exe './unit-test-directory')
|
||||
|
||||
it 'returns false when given a regular file without executable bit set', ->
|
||||
eq FALSE, (path_can_exe 'unit-test-directory/test.file')
|
||||
|
||||
it 'returns false when the given file does not exists', ->
|
||||
eq FALSE, (path_can_exe 'does-not-exist.file')
|
||||
|
||||
it 'returns true when given an executable inside $PATH', ->
|
||||
eq TRUE, (path_can_exe executable_name)
|
||||
|
||||
it 'returns true when given an executable relative to the current dir', ->
|
||||
old_dir = lfs.currentdir!
|
||||
lfs.chdir directory
|
||||
relative_executable = './' .. executable_name
|
||||
eq TRUE, (path_can_exe relative_executable)
|
||||
lfs.chdir old_dir
|
||||
|
Reference in New Issue
Block a user