diff --git a/src/imp/linux_raw/syscalls.rs b/src/imp/linux_raw/syscalls.rs index 83110bc2..1b83b622 100644 --- a/src/imp/linux_raw/syscalls.rs +++ b/src/imp/linux_raw/syscalls.rs @@ -95,8 +95,8 @@ use linux_raw_sys::general::{__NR_mmap2, __NR_set_thread_area}; use linux_raw_sys::general::{__NR_ppoll, sigset_t}; use linux_raw_sys::v5_11::general::__NR_mremap; use linux_raw_sys::v5_4::general::{ - __NR_clone, __NR_eventfd2, __NR_execveat, __NR_getrandom, __NR_membarrier, __NR_mlock2, - __NR_preadv2, __NR_prlimit64, __NR_pwritev2, __NR_userfaultfd, + __NR_clone, __NR_eventfd2, __NR_execve, __NR_execveat, __NR_getrandom, __NR_membarrier, + __NR_mlock2, __NR_preadv2, __NR_prlimit64, __NR_pwritev2, __NR_userfaultfd, }; #[cfg(target_pointer_width = "64")] use {super::conv::loff_t_from_u64, linux_raw_sys::general::__NR_mmap}; @@ -1600,6 +1600,19 @@ pub(crate) unsafe fn execveat( )) } +pub(crate) unsafe fn execve( + path: &ZStr, + args: *const *const u8, + env_vars: *const *const u8, +) -> io::Error { + ret_error(syscall3_readonly( + nr(__NR_execve), + c_str(path), + void_star(args as _), + void_star(env_vars as _), + )) +} + #[inline] pub(crate) fn wait(waitopts: WaitOptions) -> io::Result> { _waitpid(!0, waitopts) diff --git a/src/runtime.rs b/src/runtime.rs index e003e9af..e8e47b7b 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -220,13 +220,13 @@ pub unsafe fn fork() -> io::Result> { imp::syscalls::fork() } -/// `execveat(path.as_z_str(), args, env_vars)`—Execute a new command using -/// the current process. +/// `execveat(dirfd, path.as_z_str(), argv, envp, flags)`—Execute a new +/// command using the current process. /// /// # Safety /// -/// The `args` and `env_vars` slices must be NUL-terminated, and their contents -/// must be pointers to NUL-terminated byte arrays. +/// The `argv` and `envp` pointers must point to NUL-terminated arrays, and +/// their contents must be pointers to NUL-terminated byte arrays. /// /// # References /// - [Linux] @@ -244,3 +244,21 @@ pub unsafe fn execveat( let dirfd = dirfd.as_fd(); imp::syscalls::execveat(dirfd, path, argv, envp, flags) } + +/// `execve(path.as_z_str(), argv, envp)`—Execute a new command using the +/// current process. +/// +/// # Safety +/// +/// The `argv` and `envp` pointers must point to NUL-terminated arrays, and +/// their contents must be pointers to NUL-terminated byte arrays. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/execve.2.html +#[inline] +#[cfg(linux_raw)] +pub unsafe fn execve(path: &ZStr, argv: *const *const u8, envp: *const *const u8) -> io::Error { + imp::syscalls::execve(path, argv, envp) +}