Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 33 additions & 13 deletions src/imp/linux_raw/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,20 @@ use linux_raw_sys::general::{
use linux_raw_sys::general::{__NR_arch_prctl, ARCH_SET_FS};
use linux_raw_sys::general::{
__NR_chdir, __NR_clock_getres, __NR_clock_nanosleep, __NR_close, __NR_dup, __NR_dup3,
__NR_epoll_create1, __NR_epoll_ctl, __NR_exit, __NR_exit_group, __NR_faccessat, __NR_fallocate,
__NR_fchdir, __NR_fchmod, __NR_fchmodat, __NR_fdatasync, __NR_flock, __NR_fsync, __NR_futex,
__NR_getcwd, __NR_getdents64, __NR_getpid, __NR_getppid, __NR_getpriority, __NR_gettid,
__NR_ioctl, __NR_linkat, __NR_madvise, __NR_mkdirat, __NR_mknodat, __NR_mlock, __NR_mprotect,
__NR_munlock, __NR_munmap, __NR_nanosleep, __NR_openat, __NR_pipe2, __NR_prctl, __NR_pread64,
__NR_preadv, __NR_pwrite64, __NR_pwritev, __NR_read, __NR_readlinkat, __NR_readv,
__NR_sched_getaffinity, __NR_sched_setaffinity, __NR_sched_yield, __NR_set_tid_address,
__NR_setpriority, __NR_symlinkat, __NR_uname, __NR_unlinkat, __NR_utimensat, __NR_wait4,
__NR_write, __NR_writev, __kernel_gid_t, __kernel_pid_t, __kernel_timespec, __kernel_uid_t,
epoll_event, sockaddr, sockaddr_in, sockaddr_in6, sockaddr_un, socklen_t, AT_FDCWD,
AT_REMOVEDIR, AT_SYMLINK_NOFOLLOW, EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD, FIONBIO,
FIONREAD, F_DUPFD, F_DUPFD_CLOEXEC, F_GETFD, F_GETFL, F_GETLEASE, F_GETOWN, F_GETSIG, F_SETFD,
F_SETFL, PR_SET_NAME, SIGCHLD, TCGETS, TIMER_ABSTIME, TIOCEXCL, TIOCGWINSZ, TIOCNXCL,
__NR_epoll_create1, __NR_epoll_ctl, __NR_execve, __NR_exit, __NR_exit_group, __NR_faccessat,
__NR_fallocate, __NR_fchdir, __NR_fchmod, __NR_fchmodat, __NR_fdatasync, __NR_flock,
__NR_fsync, __NR_futex, __NR_getcwd, __NR_getdents64, __NR_getpid, __NR_getppid,
__NR_getpriority, __NR_gettid, __NR_ioctl, __NR_linkat, __NR_madvise, __NR_mkdirat,
__NR_mknodat, __NR_mlock, __NR_mprotect, __NR_munlock, __NR_munmap, __NR_nanosleep,
__NR_openat, __NR_pipe2, __NR_prctl, __NR_pread64, __NR_preadv, __NR_pwrite64, __NR_pwritev,
__NR_read, __NR_readlinkat, __NR_readv, __NR_sched_getaffinity, __NR_sched_setaffinity,
__NR_sched_yield, __NR_set_tid_address, __NR_setpriority, __NR_symlinkat, __NR_uname,
__NR_unlinkat, __NR_utimensat, __NR_wait4, __NR_write, __NR_writev, __kernel_gid_t,
__kernel_pid_t, __kernel_timespec, __kernel_uid_t, epoll_event, sockaddr, sockaddr_in,
sockaddr_in6, sockaddr_un, socklen_t, AT_FDCWD, AT_REMOVEDIR, AT_SYMLINK_NOFOLLOW,
EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD, FIONBIO, FIONREAD, F_DUPFD, F_DUPFD_CLOEXEC,
F_GETFD, F_GETFL, F_GETLEASE, F_GETOWN, F_GETSIG, F_SETFD, F_SETFL, PR_SET_NAME, SIGCHLD,
TCGETS, TIMER_ABSTIME, TIOCEXCL, TIOCGWINSZ, TIOCNXCL,
};
#[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))]
use linux_raw_sys::general::{__NR_dup2, __NR_open, __NR_pipe, __NR_poll};
Expand All @@ -118,6 +119,7 @@ use linux_raw_sys::v5_4::general::{
__NR_memfd_create, __NR_mlock2, __NR_preadv2, __NR_prlimit64, __NR_pwritev2, __NR_renameat2,
__NR_statx, __NR_userfaultfd, statx, F_GETPIPE_SZ, F_GET_SEALS, F_SETPIPE_SZ,
};
use std::borrow::Cow;
use std::convert::TryInto;
use std::ffi::CStr;
use std::io::{IoSlice, IoSliceMut, SeekFrom};
Expand Down Expand Up @@ -3590,6 +3592,24 @@ pub(crate) unsafe fn fork() -> io::Result<Pid> {
Ok(Pid::from_raw(pid))
}

pub fn execve(path: &CStr, args: &[Cow<'_, CStr>], env_vars: &[Cow<'_, CStr>]) -> io::Result<()> {
let mut argv: Vec<_> = args.into_iter().map(|cstr| CStr::as_ptr(cstr)).collect();
let mut envs: Vec<_> = env_vars
.into_iter()
.map(|cstr| CStr::as_ptr(cstr))
.collect();
argv.push(std::ptr::null());
envs.push(std::ptr::null());
unsafe {
ret(syscall3_readonly(
nr(__NR_execve),
c_str(path),
slice_just_addr(&argv),
slice_just_addr(&envs),
))
}
}

#[inline]
pub fn waitpid(pid: RawPid, waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> {
unsafe {
Expand Down
19 changes: 19 additions & 0 deletions src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@

#![allow(unsafe_code)]

use crate::path::Arg;
use crate::process::Pid;
use crate::{imp, io};
use std::borrow::Cow;
use std::ffi::{c_void, CStr};

#[cfg(target_arch = "x86")]
Expand Down Expand Up @@ -117,3 +119,20 @@ pub use imp::thread::tls::StartupTlsInfo;
pub unsafe fn fork() -> io::Result<Pid> {
imp::syscalls::fork()
}

/// Executes the program pointed to by `path`, with the arguments `args`,
/// and the environment variables `env_vars`.
///
/// The first argument, by convention,
/// should be the filename associated with the file being executed.
pub fn execve<P: Arg>(path: P, args: &[P], env_vars: &[P]) -> io::Result<()> {
let arg_vec: Vec<Cow<'_, CStr>> = args
.into_iter()
.map(Arg::as_cow_c_str)
.collect::<io::Result<_>>()?;
let env_vec: Vec<Cow<'_, CStr>> = env_vars
.into_iter()
.map(Arg::as_cow_c_str)
.collect::<io::Result<_>>()?;
path.into_with_c_str(|path_cstr| imp::syscalls::execve(path_cstr, &arg_vec, &env_vec))
}