diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2021-10-25 00:19:45 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2021-10-25 00:19:45 +0200 |
commit | 34ac18d20c13a78914d447fee83204811a27b1e4 (patch) | |
tree | 56763d4ea46927105fcc6a71e03d5bd75a6947a6 /crates/runner/src/util/clone.rs | |
parent | a1a185370da27f2cc3df84d3a8d7141f9ce7db16 (diff) | |
download | rebel-34ac18d20c13a78914d447fee83204811a27b1e4.tar rebel-34ac18d20c13a78914d447fee83204811a27b1e4.zip |
Move runner into separate crate
Diffstat (limited to 'crates/runner/src/util/clone.rs')
-rw-r--r-- | crates/runner/src/util/clone.rs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/crates/runner/src/util/clone.rs b/crates/runner/src/util/clone.rs new file mode 100644 index 0000000..4835b53 --- /dev/null +++ b/crates/runner/src/util/clone.rs @@ -0,0 +1,58 @@ +use std::{mem, process}; + +use nix::{errno, sched, unistd}; + +#[repr(C)] +#[derive(Debug, Default)] +struct CloneArgs { + flags: u64, + pidfd: u64, + child_tid: u64, + parent_tid: u64, + exit_signal: u64, + stack: u64, + stack_size: u64, + tls: u64, +} + +pub unsafe fn clone(flags: sched::CloneFlags) -> nix::Result<unistd::ForkResult> { + let mut args = CloneArgs { + flags: flags.bits() as u64, + exit_signal: libc::SIGCHLD as u64, + ..CloneArgs::default() + }; + let size = mem::size_of_val(&args) as libc::size_t; + + let pid = libc::syscall(libc::SYS_clone3, &mut args, size); + if pid < 0 { + Err(errno::Errno::last()) + } else if pid == 0 { + Ok(unistd::ForkResult::Child) + } else { + Ok(unistd::ForkResult::Parent { + child: unistd::Pid::from_raw(pid as libc::pid_t), + }) + } +} + +pub unsafe fn spawn<T, F>( + flags: Option<sched::CloneFlags>, + arg: T, + f: F, +) -> nix::Result<(unistd::Pid, T)> +where + F: FnOnce(T), +{ + let res = if let Some(flags) = flags { + clone(flags) + } else { + unistd::fork() + }; + match res? { + unistd::ForkResult::Parent { child } => Ok((child, arg)), + unistd::ForkResult::Child => { + f(arg); + process::exit(0) + } + } +} |