Add an execve function to runtime.

`execveat` isn't always supported, so add `execve` too, to allow
`execveat` to be emulated.
This commit is contained in:
Dan Gohman
2021-12-07 10:58:22 -08:00
parent 6818dcae0e
commit 0eea36a6b4
2 changed files with 37 additions and 6 deletions
+15 -2
View File
@@ -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<Option<(Pid, WaitStatus)>> {
_waitpid(!0, waitopts)
+22 -4
View File
@@ -220,13 +220,13 @@ pub unsafe fn fork() -> io::Result<Option<Pid>> {
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<Fd: AsFd>(
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)
}