@@ -27,6 +27,33 @@
#include <sys/syscall.h>
#include <kernel-features.h>
+static int
+__do_fexecve (int fd, char *const argv[], char *const envp[])
+{
+ /* Avoid implicit array coercion in syscall macros. */
+ int err = -INTERNAL_SYSCALL_CALL (execveat, fd, "", &argv[0], &envp[0],
+ AT_EMPTY_PATH);
+
+#ifndef __ASSUME_EXECVEAT
+ if (err == ENOSYS)
+ {
+ /* We use the /proc filesystem to get the information. If it is not
+ mounted we fail. We do not need the return value. */
+ struct fd_to_filename filename;
+ const char *path = __fd_to_filename (fd, &filename);
+ err = -INTERNAL_SYSCALL_CALL (execve, path, &argv[0], &envp[0]);
+
+ /* We come here only if the 'execve' call fails. Determine whether
+ /proc is mounted. If not we return ENOSYS. */
+ if (INTERNAL_SYSCALL_CALL (faccessat, AT_FDCWD, "/proc/self/fd", 0)
+ == -ENOENT)
+ err = ENOSYS;
+ }
+#endif /* __ASSUME_EXECVEAT */
+
+ __set_errno (err);
+ return -1;
+}
/* Execute the file FD refers to, overlaying the running program image.
ARGV and ENVP are passed to the new program, as for `execve'. */
@@ -39,29 +66,5 @@ fexecve (int fd, char *const argv[], char *const envp[])
return -1;
}
- /* Avoid implicit array coercion in syscall macros. */
- INLINE_SYSCALL (execveat, 5, fd, "", &argv[0], &envp[0], AT_EMPTY_PATH);
-#ifndef __ASSUME_EXECVEAT
- if (errno != ENOSYS)
- return -1;
-#endif
-
-#ifndef __ASSUME_EXECVEAT
- /* We use the /proc filesystem to get the information. If it is not
- mounted we fail. We do not need the return value. */
- struct fd_to_filename filename;
- __execve (__fd_to_filename (fd, &filename), argv, envp);
-
- int save = errno;
-
- /* We come here only if the 'execve' call fails. Determine whether
- /proc is mounted. If not we return ENOSYS. */
- struct __stat64_t64 st;
- if (__stat64_time64 ("/proc/self/fd", &st) != 0 && errno == ENOENT)
- save = ENOSYS;
-
- __set_errno (save);
-#endif
-
- return -1;
+ return __do_fexecve (fd, argv, envp);
}