diff --git a/meson.build b/meson.build index 04cb63d921..68ead1f849 100644 --- a/meson.build +++ b/meson.build @@ -533,6 +533,7 @@ foreach ident : [ #include #include '''], ['mallinfo', '''#include '''], + ['execveat', '''#include '''], ['close_range', '''#include '''], ] diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h index 01fec6f2f5..43d08bada7 100644 --- a/src/basic/missing_syscall.h +++ b/src/basic/missing_syscall.h @@ -735,6 +735,25 @@ static inline int missing_rt_sigqueueinfo(pid_t tgid, int sig, siginfo_t *info) # define rt_sigqueueinfo missing_rt_sigqueueinfo #endif +/* ======================================================================= */ + +#if !HAVE_EXECVEAT +static inline int missing_execveat(int dirfd, const char *pathname, + char *const argv[], char *const envp[], + int flags) { +# if defined __NR_execveat && __NR_execveat >= 0 + return syscall(__NR_execveat, dirfd, pathname, argv, envp, flags); +# else + errno = ENOSYS; + return -1; +# endif +} + +# undef AT_EMPTY_PATH +# define AT_EMPTY_PATH 0x1000 +# define execveat missing_execveat +#endif + /* ======================================================================= */ #define systemd_NR_close_range systemd_SC_arch_bias(436) diff --git a/src/shared/exec-util.c b/src/shared/exec-util.c index a0bb1567ce..d4ebeea301 100644 --- a/src/shared/exec-util.c +++ b/src/shared/exec-util.c @@ -16,6 +16,7 @@ #include "fileio.h" #include "hashmap.h" #include "macro.h" +#include "missing_syscall.h" #include "process-util.h" #include "rlimit-util.h" #include "serialize.h" @@ -445,9 +446,9 @@ ExecCommandFlags exec_command_flags_from_string(const char *s) { } int fexecve_or_execve(int executable_fd, const char *executable, char *const argv[], char *const envp[]) { - fexecve(executable_fd, argv, envp); - if (errno == ENOENT) - /* A script? Let's fall back to execve(). + execveat(executable_fd, "", argv, envp, AT_EMPTY_PATH); + if (IN_SET(errno, ENOSYS, ENOENT)) + /* Old kernel or a script? Let's fall back to execve(). * * fexecve(3): "If fd refers to a script (i.e., it is an executable text file that names a * script interpreter with a first line that begins with the characters #!) and the