return(rval);
}
+/*
+ * Like execve(2) but falls back to running through /bin/sh
+ * like execvp(3) if we get ENOEXEC.
+ */
+static int
+my_execve(const char *path, char *const argv[], char *const envp[])
+{
+ execve(path, argv, envp);
+ if (errno == ENOEXEC) {
+ int argc;
+ char **nargv;
+
+ for (argc = 0; argv[argc] != NULL; argc++)
+ continue;
+ nargv = emalloc2(argc + 2, sizeof(char *));
+ nargv[0] = "sh";
+ nargv[1] = (char *)path;
+ memcpy(nargv + 2, argv + 1, argc * sizeof(char *));
+ execve(_PATH_BSHELL, nargv, envp);
+ }
+ return -1;
+}
+
/*
* This is a little bit tricky due to how POSIX job control works and
* we fact that we have two different controlling terminals to deal with.
selinux_execve(details->command, argv, envp);
else
#endif
- execve(details->command, argv, envp);
+ my_execve(details->command, argv, envp);
}
- /* XXX - fallback to sh */
}
cstat->type = CMD_ERRNO;
cstat->val = errno;
selinux_execve(path, argv, envp);
else
#endif
- execve(path, argv, envp);
+ my_execve(path, argv, envp);
}
static void