summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/eval.c8
-rw-r--r--src/ex_getln.c18
-rw-r--r--src/misc1.c6
-rw-r--r--src/os_amiga.c4
-rw-r--r--src/os_msdos.c11
-rw-r--r--src/os_unix.c21
-rw-r--r--src/os_vms.c3
-rw-r--r--src/proto/os_amiga.pro2
-rw-r--r--src/proto/os_msdos.pro2
-rw-r--r--src/proto/os_unix.pro2
-rw-r--r--src/proto/os_win32.pro2
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h2
13 files changed, 62 insertions, 21 deletions
diff --git a/src/eval.c b/src/eval.c
index 7aefdb58f..ebd7e379e 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -10271,7 +10271,11 @@ f_executable(argvars, rettv)
typval_T *argvars;
typval_T *rettv;
{
- rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0]), NULL);
+ char_u *name = get_tv_string(&argvars[0]);
+
+ /* Check in $PATH and also check directly if there is a directory name. */
+ rettv->vval.v_number = mch_can_exe(name, NULL, TRUE)
+ || (gettail(name) != name && mch_can_exe(name, NULL, FALSE));
}
/*
@@ -10284,7 +10288,7 @@ f_exepath(argvars, rettv)
{
char_u *p = NULL;
- (void)mch_can_exe(get_tv_string(&argvars[0]), &p);
+ (void)mch_can_exe(get_tv_string(&argvars[0]), &p, TRUE);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = p;
}
diff --git a/src/ex_getln.c b/src/ex_getln.c
index e18a8ede9..31e61d094 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -4885,6 +4885,7 @@ expand_shellcmd(filepat, num_file, file, flagsarg)
char_u *s, *e;
int flags = flagsarg;
int ret;
+ int did_curdir = FALSE;
if (buf == NULL)
return FAIL;
@@ -4896,7 +4897,7 @@ expand_shellcmd(filepat, num_file, file, flagsarg)
if (pat[i] == '\\' && pat[i + 1] == ' ')
STRMOVE(pat + i, pat + i + 1);
- flags |= EW_FILE | EW_EXEC;
+ flags |= EW_FILE | EW_EXEC | EW_SHELLCMD;
/* For an absolute name we don't use $PATH. */
if (mch_isFullName(pat))
@@ -4913,11 +4914,22 @@ expand_shellcmd(filepat, num_file, file, flagsarg)
/*
* Go over all directories in $PATH. Expand matches in that directory and
- * collect them in "ga".
+ * collect them in "ga". When "." is not in $PATH also expand for the
+ * current directory, to find "subdir/cmd".
*/
ga_init2(&ga, (int)sizeof(char *), 10);
- for (s = path; *s != NUL; s = e)
+ for (s = path; ; s = e)
{
+ if (*s == NUL)
+ {
+ if (did_curdir)
+ break;
+ /* Find directories in the current directory, path is empty. */
+ did_curdir = TRUE;
+ }
+ else if (*s == '.')
+ did_curdir = TRUE;
+
if (*s == ' ')
++s; /* Skip space used for absolute path name. */
diff --git a/src/misc1.c b/src/misc1.c
index 940a3e917..bd1fe255b 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -10987,8 +10987,10 @@ addfile(gap, f, flags)
if ((isdir && !(flags & EW_DIR)) || (!isdir && !(flags & EW_FILE)))
return;
- /* If the file isn't executable, may not add it. Do accept directories. */
- if (!isdir && (flags & EW_EXEC) && !mch_can_exe(f, NULL))
+ /* If the file isn't executable, may not add it. Do accept directories.
+ * When invoked from expand_shellcmd() do not use $PATH. */
+ if (!isdir && (flags & EW_EXEC)
+ && !mch_can_exe(f, NULL, !(flags & EW_SHELLCMD)))
return;
/* Make room for another item in the file list. */
diff --git a/src/os_amiga.c b/src/os_amiga.c
index 324fc367b..ccd3b0c1c 100644
--- a/src/os_amiga.c
+++ b/src/os_amiga.c
@@ -881,12 +881,14 @@ mch_mkdir(name)
/*
* Return 1 if "name" can be executed, 0 if not.
+ * If "use_path" is FALSE only check if "name" is executable.
* Return -1 if unknown.
*/
int
-mch_can_exe(name, path)
+mch_can_exe(name, path, use_path)
char_u *name;
char_u **path;
+ int use_path;
{
/* TODO */
return -1;
diff --git a/src/os_msdos.c b/src/os_msdos.c
index f24a6f8ea..1b75a30f7 100644
--- a/src/os_msdos.c
+++ b/src/os_msdos.c
@@ -2942,15 +2942,24 @@ mch_isdir(char_u *name)
/*
* Return 1 if "name" can be executed, 0 if not.
+ * If "use_path" is FALSE only check if "name" is executable.
* Return -1 if unknown.
*/
int
-mch_can_exe(name, path)
+mch_can_exe(name, path, use_path)
char_u *name;
char_u **path;
+ int use_path;
{
char *p;
+ int mode;
+ if (!use_path)
+ {
+ /* TODO: proper check if file is executable. */
+ mode = vim_chmod(name);
+ return mode != -1 && (mode & FA_DIREC) == 0;
+ }
p = searchpath(name);
if (p == NULL || mch_isdir(p))
return FALSE;
diff --git a/src/os_unix.c b/src/os_unix.c
index 8f6b9143e..df045a50f 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3104,22 +3104,27 @@ executable_file(name)
/*
* Return 1 if "name" can be found in $PATH and executed, 0 if not.
+ * If "use_path" is FALSE only check if "name" is executable.
* Return -1 if unknown.
*/
int
-mch_can_exe(name, path)
+mch_can_exe(name, path, use_path)
char_u *name;
char_u **path;
+ int use_path;
{
char_u *buf;
char_u *p, *e;
int retval;
- /* If it's an absolute or relative path don't need to use $PATH. */
- if (mch_isFullName(name) || (name[0] == '.' && (name[1] == '/'
- || (name[1] == '.' && name[2] == '/'))))
+ /* When "use_path" is false and if it's an absolute or relative path don't
+ * need to use $PATH. */
+ if (!use_path || mch_isFullName(name) || (name[0] == '.'
+ && (name[1] == '/' || (name[1] == '.' && name[2] == '/'))))
{
- if (executable_file(name))
+ /* There must be a path separator, files in the current directory
+ * can't be executed. */
+ if (gettail(name) != name && executable_file(name))
{
if (path != NULL)
{
@@ -5730,7 +5735,8 @@ mch_expand_wildcards(num_pat, pat, num_file, file, flags)
continue;
/* Skip files that are not executable if we check for that. */
- if (!dir && (flags & EW_EXEC) && !mch_can_exe(p, NULL))
+ if (!dir && (flags & EW_EXEC)
+ && !mch_can_exe(p, NULL, !(flags & EW_SHELLCMD)))
continue;
if (--files_free == 0)
@@ -6230,7 +6236,8 @@ mch_expand_wildcards(num_pat, pat, num_file, file, flags)
continue;
/* Skip files that are not executable if we check for that. */
- if (!dir && (flags & EW_EXEC) && !mch_can_exe((*file)[i], NULL))
+ if (!dir && (flags & EW_EXEC)
+ && !mch_can_exe((*file)[i], NULL, !(flags & EW_SHELLCMD)))
continue;
p = alloc((unsigned)(STRLEN((*file)[i]) + 1 + dir));
diff --git a/src/os_vms.c b/src/os_vms.c
index 12eceedd0..7c2d87255 100644
--- a/src/os_vms.c
+++ b/src/os_vms.c
@@ -483,7 +483,8 @@ mch_expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file, i
continue;
/* Skip files that are not executable if we check for that. */
- if (!dir && (flags & EW_EXEC) && !mch_can_exe(vms_fmatch[i], NULL))
+ if (!dir && (flags & EW_EXEC)
+ && !mch_can_exe(vms_fmatch[i], NULL, !(flags & EW_SHELLCMD)))
continue;
/* allocate memory for pointers */
diff --git a/src/proto/os_amiga.pro b/src/proto/os_amiga.pro
index 16ee6571d..24c1f7248 100644
--- a/src/proto/os_amiga.pro
+++ b/src/proto/os_amiga.pro
@@ -26,7 +26,7 @@ int mch_setperm __ARGS((char_u *name, long perm));
void mch_hide __ARGS((char_u *name));
int mch_isdir __ARGS((char_u *name));
int mch_mkdir __ARGS((char_u *name));
-int mch_can_exe __ARGS((char_u *name, char_u **path));
+int mch_can_exe __ARGS((char_u *name, char_u **path, int use_path));
int mch_nodetype __ARGS((char_u *name));
void mch_early_init __ARGS((void));
void mch_exit __ARGS((int r));
diff --git a/src/proto/os_msdos.pro b/src/proto/os_msdos.pro
index e75521110..e035b9509 100644
--- a/src/proto/os_msdos.pro
+++ b/src/proto/os_msdos.pro
@@ -38,7 +38,7 @@ long mch_getperm __ARGS((char_u *name));
int mch_setperm __ARGS((char_u *name, long perm));
void mch_hide __ARGS((char_u *name));
int mch_isdir __ARGS((char_u *name));
-int mch_can_exe __ARGS((char_u *name, char_u **path));
+int mch_can_exe __ARGS((char_u *name, char_u **path, int use_path));
int mch_nodetype __ARGS((char_u *name));
int mch_dirname __ARGS((char_u *buf, int len));
int mch_remove __ARGS((char_u *name));
diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro
index a59b6aa5e..23434ba9f 100644
--- a/src/proto/os_unix.pro
+++ b/src/proto/os_unix.pro
@@ -42,7 +42,7 @@ void mch_set_acl __ARGS((char_u *fname, vim_acl_T aclent));
void mch_free_acl __ARGS((vim_acl_T aclent));
void mch_hide __ARGS((char_u *name));
int mch_isdir __ARGS((char_u *name));
-int mch_can_exe __ARGS((char_u *name, char_u **path));
+int mch_can_exe __ARGS((char_u *name, char_u **path, int use_path));
int mch_nodetype __ARGS((char_u *name));
void mch_early_init __ARGS((void));
void mch_free_mem __ARGS((void));
diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro
index c149bc89f..cbabe3a9f 100644
--- a/src/proto/os_win32.pro
+++ b/src/proto/os_win32.pro
@@ -26,7 +26,7 @@ int mch_is_symbolic_link __ARGS((char_u *fname));
int mch_is_linked __ARGS((char_u *fname));
int win32_fileinfo __ARGS((char_u *fname, BY_HANDLE_FILE_INFORMATION *info));
int mch_writable __ARGS((char_u *name));
-int mch_can_exe __ARGS((char_u *name, char_u **path));
+int mch_can_exe __ARGS((char_u *name, char_u **path, int use_path));
int mch_nodetype __ARGS((char_u *name));
vim_acl_T mch_get_acl __ARGS((char_u *fname));
void mch_set_acl __ARGS((char_u *fname, vim_acl_T acl));
diff --git a/src/version.c b/src/version.c
index 405b8a7ce..344c327dd 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 672,
+/**/
671,
/**/
670,
diff --git a/src/vim.h b/src/vim.h
index 825c844c2..fe8f55828 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -841,6 +841,8 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
/* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
* is used when executing commands and EW_SILENT for interactive expanding. */
#define EW_ALLLINKS 0x1000 /* also links not pointing to existing file */
+#define EW_SHELLCMD 0x2000 /* called from expand_shellcmd(), don't check
+ * if executable is in $PATH */
/* Flags for find_file_*() functions. */
#define FINDFILE_FILE 0 /* only files */