diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-20 14:28:05 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-20 14:38:17 +0200 |
commit | e9bf0fc40c0eb7e9d4228b804d62f31b0a136528 (patch) | |
tree | 7872f587782d5635eadbf82ae861d474d4da2efe /crates/rebel-runner/src/util/clone.rs | |
parent | 35e68444dd5e9d3d5fc39409c48be6eb3fa05e07 (diff) | |
download | rebel-e9bf0fc40c0eb7e9d4228b804d62f31b0a136528.tar rebel-e9bf0fc40c0eb7e9d4228b804d62f31b0a136528.zip |
Rename directories to match crate names
Diffstat (limited to 'crates/rebel-runner/src/util/clone.rs')
-rw-r--r-- | crates/rebel-runner/src/util/clone.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/crates/rebel-runner/src/util/clone.rs b/crates/rebel-runner/src/util/clone.rs new file mode 100644 index 0000000..51a31c3 --- /dev/null +++ b/crates/rebel-runner/src/util/clone.rs @@ -0,0 +1,59 @@ +use std::{mem, process}; + +use nix::{ + errno, sched, + unistd::{self, Pid}, +}; + +#[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); + + #[allow(clippy::comparison_chain)] + if pid < 0 { + Err(errno::Errno::last()) + } else if pid == 0 { + Ok(unistd::ForkResult::Child) + } else { + Ok(unistd::ForkResult::Parent { + child: Pid::from_raw(pid as libc::pid_t), + }) + } +} + +pub unsafe fn spawn<F>(flags: Option<sched::CloneFlags>, f: F) -> nix::Result<Pid> +where + F: FnOnce(), +{ + let res = if let Some(flags) = flags { + clone(flags) + } else { + unistd::fork() + }; + match res? { + unistd::ForkResult::Parent { child } => Ok(child), + unistd::ForkResult::Child => { + f(); + process::exit(0) + } + } +} |