clone3 wrapper
This commit is contained in:
parent
b46cc001be
commit
565c1567c4
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "rust-lang.rust"
|
||||
}
|
241
Cargo.lock
generated
Normal file
241
Cargo.lock
generated
Normal file
@ -0,0 +1,241 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clone-shim"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"libc",
|
||||
"log",
|
||||
"nix",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
14
Cargo.toml
Normal file
14
Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "clone-shim"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
env_logger = "0.9"
|
||||
thiserror = "1"
|
||||
|
||||
libc = "0.2.117"
|
||||
nix = "0.23.1"
|
130
src/clone.rs
Normal file
130
src/clone.rs
Normal file
@ -0,0 +1,130 @@
|
||||
use std::fs::File;
|
||||
use std::marker::PhantomData;
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
||||
|
||||
use libc::{pid_t, syscall, SYS_clone3};
|
||||
use nix::errno::Errno;
|
||||
pub use nix::sched::CloneFlags;
|
||||
use nix::sys::signal::Signal;
|
||||
use nix::unistd::Pid;
|
||||
|
||||
pub struct CloneArgs<'a> {
|
||||
pub flags: CloneFlags,
|
||||
|
||||
pub pidfd: Option<&'a mut File>,
|
||||
pidfd_int: RawFd,
|
||||
|
||||
pub child_tid: Option<&'a mut Pid>,
|
||||
child_tid_int: pid_t,
|
||||
|
||||
pub parent_tid: Option<&'a mut Pid>,
|
||||
parent_tid_int: pid_t,
|
||||
|
||||
pub exit_signal: Option<Signal>,
|
||||
|
||||
pub stack: Option<&'a mut [u8]>,
|
||||
pub set_tid: Option<&'a [Pid]>,
|
||||
pub cgroup: Option<&'a File>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct CloneArgsInternal<'a> {
|
||||
flags: u64,
|
||||
pidfd: u64,
|
||||
child_tid: u64,
|
||||
parent_tid: u64,
|
||||
exit_signal: u64,
|
||||
stack: u64,
|
||||
stack_size: u64,
|
||||
tls: u64,
|
||||
set_tid: u64,
|
||||
set_tid_size: u64,
|
||||
cgroup: u64,
|
||||
|
||||
phantom: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a: 'b, 'b: 'c, 'c> CloneArgs<'a> {
|
||||
pub fn new(flags: CloneFlags) -> CloneArgs<'a> {
|
||||
CloneArgs {
|
||||
flags,
|
||||
|
||||
pidfd: None,
|
||||
pidfd_int: 0,
|
||||
|
||||
child_tid: None,
|
||||
child_tid_int: 0,
|
||||
|
||||
parent_tid: None,
|
||||
parent_tid_int: 0,
|
||||
|
||||
exit_signal: None,
|
||||
|
||||
stack: None,
|
||||
set_tid: None,
|
||||
cgroup: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn process(&'b mut self) -> CloneArgsInternal<'c> {
|
||||
CloneArgsInternal {
|
||||
flags: self.flags.bits() as u64,
|
||||
pidfd: self
|
||||
.pidfd
|
||||
.as_ref()
|
||||
.map(|_| (self.pidfd_int) as *mut RawFd as u64)
|
||||
.unwrap_or(0),
|
||||
child_tid: self
|
||||
.child_tid
|
||||
.as_ref()
|
||||
.map(|_| self.child_tid_int as *mut pid_t as u64)
|
||||
.unwrap_or(0),
|
||||
parent_tid: self
|
||||
.parent_tid
|
||||
.as_ref()
|
||||
.map(|_| self.parent_tid_int as *mut pid_t as u64)
|
||||
.unwrap_or(0),
|
||||
exit_signal: self.exit_signal.map(|s| s as i32 as u64).unwrap_or(0),
|
||||
stack: self
|
||||
.stack
|
||||
.as_mut()
|
||||
.map(|s| s.as_mut_ptr() as u64)
|
||||
.unwrap_or(0),
|
||||
stack_size: self.stack.as_ref().map(|s| s.len() as u64).unwrap_or(0),
|
||||
tls: 0,
|
||||
set_tid: self
|
||||
.set_tid
|
||||
.as_ref()
|
||||
.map(|s| s.as_ptr() as u64)
|
||||
.unwrap_or(0),
|
||||
set_tid_size: self.set_tid.as_ref().map(|s| s.len() as u64).unwrap_or(0),
|
||||
cgroup: self.cgroup.map(|c| c.as_raw_fd() as u64).unwrap_or(0),
|
||||
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn finalise(&mut self) {
|
||||
if let Some(r) = &mut self.pidfd {
|
||||
**r = unsafe { File::from_raw_fd(self.pidfd_int) };
|
||||
}
|
||||
if let Some(r) = &mut self.child_tid {
|
||||
**r = Pid::from_raw(self.child_tid_int);
|
||||
}
|
||||
if let Some(r) = &mut self.parent_tid {
|
||||
**r = Pid::from_raw(self.parent_tid_int);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone3(mut args: CloneArgs) -> nix::Result<Pid> {
|
||||
let args_int: CloneArgsInternal = args.process();
|
||||
|
||||
let result = unsafe { syscall(SYS_clone3, &args_int, std::mem::size_of_val(&args_int)) };
|
||||
|
||||
let out = Errno::result(result).map(|p| Pid::from_raw(p as i32))?;
|
||||
|
||||
args.finalise();
|
||||
|
||||
Ok(out)
|
||||
}
|
7
src/error.rs
Normal file
7
src/error.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error {
|
||||
#[error("{msg}: {src}")]
|
||||
Nix { msg: &'static str, src: nix::Error },
|
||||
}
|
28
src/main.rs
Normal file
28
src/main.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use log::info;
|
||||
|
||||
mod clone;
|
||||
mod error;
|
||||
|
||||
use clone::{clone3, CloneArgs, CloneFlags};
|
||||
use error::Error;
|
||||
|
||||
use nix::unistd::Pid;
|
||||
|
||||
fn main() -> Result<(), Error> {
|
||||
let env = env_logger::Env::new().filter_or("LOG", "info");
|
||||
env_logger::init_from_env(env);
|
||||
|
||||
info!("getting started");
|
||||
|
||||
if clone3(CloneArgs::new(CloneFlags::empty())).map_err(|e| Error::Nix {
|
||||
msg: "clone3",
|
||||
src: e,
|
||||
})? != Pid::from_raw(0)
|
||||
{
|
||||
info!("hello from the child");
|
||||
} else {
|
||||
info!("hello from the parent");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user