}
}
+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)
{
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;
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);