Move the logic for 'is_executable()' from help.c to exec_cmd.c and expose it so that callers from outside help.c can access the function. This is to enable run-command to be able to query if a file is executable in a future patch. Signed-off-by: Brandon Williams <bmwill@xxxxxxxxxx> --- exec_cmd.c | 42 ++++++++++++++++++++++++++++++++++++++++++ exec_cmd.h | 1 + help.c | 42 ------------------------------------------ 3 files changed, 43 insertions(+), 42 deletions(-) diff --git a/exec_cmd.c b/exec_cmd.c index fb94aeba9..6d9481e26 100644 --- a/exec_cmd.c +++ b/exec_cmd.c @@ -149,3 +149,45 @@ int execl_git_cmd(const char *cmd,...) argv[argc] = NULL; return execv_git_cmd(argv); } + +int is_executable(const char *name) +{ + struct stat st; + + if (stat(name, &st) || /* stat, not lstat */ + !S_ISREG(st.st_mode)) + return 0; + +#if defined(GIT_WINDOWS_NATIVE) + /* + * On Windows there is no executable bit. The file extension + * indicates whether it can be run as an executable, and Git + * has special-handling to detect scripts and launch them + * through the indicated script interpreter. We test for the + * file extension first because virus scanners may make + * it quite expensive to open many files. + */ + if (ends_with(name, ".exe")) + return S_IXUSR; + +{ + /* + * Now that we know it does not have an executable extension, + * peek into the file instead. + */ + char buf[3] = { 0 }; + int n; + int fd = open(name, O_RDONLY); + st.st_mode &= ~S_IXUSR; + if (fd >= 0) { + n = read(fd, buf, 2); + if (n == 2) + /* look for a she-bang */ + if (!strcmp(buf, "#!")) + st.st_mode |= S_IXUSR; + close(fd); + } +} +#endif + return st.st_mode & S_IXUSR; +} diff --git a/exec_cmd.h b/exec_cmd.h index ff0b48048..48dd18a0d 100644 --- a/exec_cmd.h +++ b/exec_cmd.h @@ -12,5 +12,6 @@ extern int execv_git_cmd(const char **argv); /* NULL terminated */ LAST_ARG_MUST_BE_NULL extern int execl_git_cmd(const char *cmd, ...); extern char *system_path(const char *path); +extern int is_executable(const char *name); #endif /* GIT_EXEC_CMD_H */ diff --git a/help.c b/help.c index bc6cd19cf..50f84b430 100644 --- a/help.c +++ b/help.c @@ -96,48 +96,6 @@ static void pretty_print_cmdnames(struct cmdnames *cmds, unsigned int colopts) string_list_clear(&list, 0); } -static int is_executable(const char *name) -{ - struct stat st; - - if (stat(name, &st) || /* stat, not lstat */ - !S_ISREG(st.st_mode)) - return 0; - -#if defined(GIT_WINDOWS_NATIVE) - /* - * On Windows there is no executable bit. The file extension - * indicates whether it can be run as an executable, and Git - * has special-handling to detect scripts and launch them - * through the indicated script interpreter. We test for the - * file extension first because virus scanners may make - * it quite expensive to open many files. - */ - if (ends_with(name, ".exe")) - return S_IXUSR; - -{ - /* - * Now that we know it does not have an executable extension, - * peek into the file instead. - */ - char buf[3] = { 0 }; - int n; - int fd = open(name, O_RDONLY); - st.st_mode &= ~S_IXUSR; - if (fd >= 0) { - n = read(fd, buf, 2); - if (n == 2) - /* look for a she-bang */ - if (!strcmp(buf, "#!")) - st.st_mode |= S_IXUSR; - close(fd); - } -} -#endif - return st.st_mode & S_IXUSR; -} - static void list_commands_in_dir(struct cmdnames *cmds, const char *path, const char *prefix) -- 2.13.0.rc0.306.g87b477812d-goog