Skip to content

Commit 38124a4

Browse files
bmwillgitster
authored andcommitted
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>
1 parent 45afb1c commit 38124a4

3 files changed

Lines changed: 44 additions & 42 deletions

File tree

help.c

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "cache.h"
22
#include "builtin.h"
33
#include "exec_cmd.h"
4+
#include "run-command.h"
45
#include "levenshtein.h"
56
#include "help.h"
67
#include "common-cmds.h"
@@ -96,48 +97,6 @@ static void pretty_print_cmdnames(struct cmdnames *cmds, unsigned int colopts)
9697
string_list_clear(&list, 0);
9798
}
9899

99-
static int is_executable(const char *name)
100-
{
101-
struct stat st;
102-
103-
if (stat(name, &st) || /* stat, not lstat */
104-
!S_ISREG(st.st_mode))
105-
return 0;
106-
107-
#if defined(GIT_WINDOWS_NATIVE)
108-
/*
109-
* On Windows there is no executable bit. The file extension
110-
* indicates whether it can be run as an executable, and Git
111-
* has special-handling to detect scripts and launch them
112-
* through the indicated script interpreter. We test for the
113-
* file extension first because virus scanners may make
114-
* it quite expensive to open many files.
115-
*/
116-
if (ends_with(name, ".exe"))
117-
return S_IXUSR;
118-
119-
{
120-
/*
121-
* Now that we know it does not have an executable extension,
122-
* peek into the file instead.
123-
*/
124-
char buf[3] = { 0 };
125-
int n;
126-
int fd = open(name, O_RDONLY);
127-
st.st_mode &= ~S_IXUSR;
128-
if (fd >= 0) {
129-
n = read(fd, buf, 2);
130-
if (n == 2)
131-
/* look for a she-bang */
132-
if (!strcmp(buf, "#!"))
133-
st.st_mode |= S_IXUSR;
134-
close(fd);
135-
}
136-
}
137-
#endif
138-
return st.st_mode & S_IXUSR;
139-
}
140-
141100
static void list_commands_in_dir(struct cmdnames *cmds,
142101
const char *path,
143102
const char *prefix)

run-command.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,48 @@ static inline void close_pair(int fd[2])
117117
close(fd[1]);
118118
}
119119

120+
int is_executable(const char *name)
121+
{
122+
struct stat st;
123+
124+
if (stat(name, &st) || /* stat, not lstat */
125+
!S_ISREG(st.st_mode))
126+
return 0;
127+
128+
#if defined(GIT_WINDOWS_NATIVE)
129+
/*
130+
* On Windows there is no executable bit. The file extension
131+
* indicates whether it can be run as an executable, and Git
132+
* has special-handling to detect scripts and launch them
133+
* through the indicated script interpreter. We test for the
134+
* file extension first because virus scanners may make
135+
* it quite expensive to open many files.
136+
*/
137+
if (ends_with(name, ".exe"))
138+
return S_IXUSR;
139+
140+
{
141+
/*
142+
* Now that we know it does not have an executable extension,
143+
* peek into the file instead.
144+
*/
145+
char buf[3] = { 0 };
146+
int n;
147+
int fd = open(name, O_RDONLY);
148+
st.st_mode &= ~S_IXUSR;
149+
if (fd >= 0) {
150+
n = read(fd, buf, 2);
151+
if (n == 2)
152+
/* look for a she-bang */
153+
if (!strcmp(buf, "#!"))
154+
st.st_mode |= S_IXUSR;
155+
close(fd);
156+
}
157+
}
158+
#endif
159+
return st.st_mode & S_IXUSR;
160+
}
161+
120162
static char *locate_in_PATH(const char *file)
121163
{
122164
const char *p = getenv("PATH");

run-command.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ struct child_process {
5151
#define CHILD_PROCESS_INIT { NULL, ARGV_ARRAY_INIT, ARGV_ARRAY_INIT }
5252
void child_process_init(struct child_process *);
5353
void child_process_clear(struct child_process *);
54+
extern int is_executable(const char *name);
5455

5556
int start_command(struct child_process *);
5657
int finish_command(struct child_process *);

0 commit comments

Comments
 (0)