1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-06 20:26:11 +02:00

run-command: expose is_executable function

Move the logic for 'is_executable()' from help.c to run_command.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@google.com>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Brandon Williams 2017-04-25 16:46:59 -07:00 committed by Junio C Hamano
parent 45afb1ca9c
commit 38124a40e4
3 changed files with 44 additions and 42 deletions

43
help.c
View File

@ -1,6 +1,7 @@
#include "cache.h"
#include "builtin.h"
#include "exec_cmd.h"
#include "run-command.h"
#include "levenshtein.h"
#include "help.h"
#include "common-cmds.h"
@ -96,48 +97,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)

View File

@ -117,6 +117,48 @@ static inline void close_pair(int fd[2])
close(fd[1]);
}
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 char *locate_in_PATH(const char *file)
{
const char *p = getenv("PATH");

View File

@ -51,6 +51,7 @@ struct child_process {
#define CHILD_PROCESS_INIT { NULL, ARGV_ARRAY_INIT, ARGV_ARRAY_INIT }
void child_process_init(struct child_process *);
void child_process_clear(struct child_process *);
extern int is_executable(const char *name);
int start_command(struct child_process *);
int finish_command(struct child_process *);