git help -a scans the PATH for git commands. On Windows it failed for two
reasons:
- The PATH separator is ';', not ':' on Windows.
- stat() does not set the executabe bit.
We now open the file and guess whether it is executable.
The result of the guess is good enough for the list of git commands, but
it is of no use for a general stat() implementation because (1) it is a
guess, (2) the user has no way to influence the outcome (via chmod or
similar), and (3) it would reduce stat() performance by an unacceptable
amount. Therefore, this strategy is a special-case local to help.c.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
help.c | 38 +++++++++++++++++++++++++++++++++-----
1 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/help.c b/help.c
index 8143dcd..0248c76 100644
--- a/help.c
+++ b/help.c
@@ -163,6 +163,32 @@ static void pretty_print_string_list(struct cmdnames *cmds, int longest)
}
}
+static int is_executable(const char *name)
+{
+ struct stat st;
+
+ if (stat(name, &st) || /* stat, not lstat */
+ !S_ISREG(st.st_mode))
+ return 0;
+
+#ifdef __MINGW32__
+ /* cannot trust the executable bit, 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)
+ /* DOS executables start with "MZ" */
+ if (!strcmp(buf, "#!") || !strcmp(buf, "MZ"))
+ st.st_mode |= S_IXUSR;
+ close(fd);
+ }
+#endif
+ return st.st_mode & S_IXUSR;
+}
+
static unsigned int list_commands_in_dir(struct cmdnames *cmds,
const char *path)
{
@@ -176,15 +202,12 @@ static unsigned int list_commands_in_dir(struct cmdnames *cmds,
return 0;
while ((de = readdir(dir)) != NULL) {
- struct stat st;
int entlen;
if (prefixcmp(de->d_name, prefix))
continue;
- if (stat(de->d_name, &st) || /* stat, not lstat */
- !S_ISREG(st.st_mode) ||
- !(st.st_mode & S_IXUSR))
+ if (!is_executable(de->d_name))
continue;
entlen = strlen(de->d_name) - prefix_len;
@@ -208,6 +231,11 @@ static void list_commands(void)
const char *env_path = getenv("PATH");
char *paths, *path, *colon;
const char *exec_path = git_exec_path();
+#ifdef __MINGW32__
+ char sep = ';';
+#else
+ char sep = ':';
+#endif
if (exec_path)
longest = list_commands_in_dir(&main_cmds, exec_path);
@@ -219,7 +247,7 @@ static void list_commands(void)
path = paths = xstrdup(env_path);
while (1) {
- if ((colon = strchr(path, ':')))
+ if ((colon = strchr(path, sep)))
*colon = 0;
len = list_commands_in_dir(&other_cmds, path);
--
1.5.4.1.126.ge5a7d
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
| Linus Torvalds | Re: Dual-Licensing Linux Kernel with GPL V2 and GPL V3 |
| Tony Lindgren | [PATCH 37/90] ARM: OMAP: MPUIO wake updates |
| Greg KH | [GIT PATCH] driver core patches against 2.6.24 |
| Miklos Szeredi | -rt doesn't compile for UML |
git: | |
| Florian Weimer | Re: Handling large files with GIT |
| Dana How | [PATCH] Prevent megablobs from gunking up git packs |
| Denis Bueno | Recovering from repository corruption |
| Peter Stahlir | Git as a filesystem |
| Richard Stallman | Real men don't attack straw men |
| Brian A. Seklecki | sshd_config(5) PermitRootLogin yes |
| Theo de Raadt | Re: dmesg IBM x3650 OpenBSD 4.3 |
| Stuart Henderson | Re: Actual BIND error - Patching OpenBSD 4.3 named ? |
| Auke Kok | [PATCH 5/6] e1000: Secondary unicast address support |
| Jon Nelson | tg3: strange errors and non-working-ness |
| Indan Zupancic | Re: Realtek 8111C transmit timed out |
| Brandeburg, Jesse | RE: 2.6.24 BUG: soft lockup - CPU#X |
| usb mic not detected | 4 hours ago | Applications and Utilities |
| Problem in Inserting a module | 4 hours ago | Linux kernel |
| Treason Uncloaked | 10 hours ago | Linux kernel |
| Shared swap partition | 21 hours ago | Linux general |
| high memory | 2 days ago | Linux kernel |
| semaphore access speed | 2 days ago | Applications and Utilities |
| the kernel how to power off the machine | 2 days ago | Linux kernel |
| Easter Eggs in windows XP | 2 days ago | Windows |
| Root password | 3 days ago | Linux general |
| Where/when DNOTIFY is used? | 3 days ago | Linux kernel |
