X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=help.c;h=6c16fb4aa1406dd955c7ae1b0efd74288d72c239;hb=cc3b7a9732f940cb0249a12cb3c02e3d83723eb0;hp=8aff94c64a1204f8a359e522a554f29c8f0fdc20;hpb=b2f5e2684da060dd821bf90f88df8b6dc9401a40;p=git.git diff --git a/help.c b/help.c index 8aff94c64..6c16fb4aa 100644 --- a/help.c +++ b/help.c @@ -391,6 +391,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) { @@ -404,15 +430,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; @@ -447,7 +470,7 @@ static unsigned int load_command_list(void) path = paths = xstrdup(env_path); while (1) { - if ((colon = strchr(path, ':'))) + if ((colon = strchr(path, PATH_SEP))) *colon = 0; len = list_commands_in_dir(&other_cmds, path);