use core::{
arch::asm,
mem,
};
use crate::{
pid_t,
result_from_value,
};
pub const CLONE_NEWTIME: u32 = 0x80;
pub const CLONE_VM: u32 = 0x100;
pub const CLONE_FS: u32 = 0x200;
pub const CLONE_FILES: u32 = 0x400;
pub const CLONE_SIGHAND: u32 = 0x800;
pub const CLONE_PIDFD: u32 = 0x1000;
pub const CLONE_PTRACE: u32 = 0x2000;
pub const CLONE_VFORK: u32 = 0x4000;
pub const CLONE_PARENT: u32 = 0x8000;
pub const CLONE_THREAD: u32 = 0x10000;
pub const CLONE_NEWNS: u32 = 0x20000;
pub const CLONE_SYSVSEM: u32 = 0x40000;
pub const CLONE_SETTLS: u32 = 0x80000;
pub const CLONE_PARENT_SETTID: u32 = 0x100000;
pub const CLONE_CHILD_CLEARTID: u32 = 0x200000;
pub const CLONE_DETACHED: u32 = 0x400000;
pub const CLONE_UNTRACED: u32 = 0x800000;
pub const CLONE_CHILD_SETTID: u32 = 0x1000000;
pub const CLONE_NEWCGROUP: u32 = 0x2000000;
pub const CLONE_NEWUTS: u32 = 0x4000000;
pub const CLONE_NEWIPC: u32 = 0x8000000;
pub const CLONE_NEWUSER: u32 = 0x10000000;
pub const CLONE_NEWPID: u32 = 0x20000000;
pub const CLONE_NEWNET: u32 = 0x40000000;
pub const CLONE_IO: u32 = 0x80000000;
#[allow(non_camel_case_types)]
#[repr(C)]
pub struct clone_args {
pub flags: u64,
pub pidfd: u64,
pub child_tid: u64,
pub parent_tid: u64,
pub exit_signal: u64,
pub stack: u64,
pub stack_size: u64,
pub tls: u64,
pub set_tid: u64,
pub set_tid_size: u64,
pub cgroup: u64,
}
#[inline]
#[allow(clippy::missing_safety_doc)]
pub unsafe fn clone(
flags: u32,
sp: *mut u8,
tid_parent: *mut i32,
tid_child: *mut i32,
tls: *mut u8,
cb: unsafe fn(user_data: usize) -> !,
user_data: usize,
) -> crate::Result<pid_t> {
let ret: i32;
asm!(
"syscall",
"test rax, rax",
"jnz 1f",
"xor ebp, ebp",
"mov rdi, r12",
"call r9",
"1:",
in("r9") cb,
in("r12") user_data,
in("rax") 56,
in("rdi") flags,
in("rsi") sp,
in("rdx") tid_parent,
in("r10") tid_child,
in("r8") tls,
lateout("eax") ret,
out("rcx") _,
out("r11") _,
);
result_from_value(ret)
}
#[inline]
#[allow(clippy::missing_safety_doc)]
pub unsafe fn clone3(
args: &mut clone_args,
cb: unsafe fn(user_data: usize) -> !,
user_data: usize,
) -> crate::Result<pid_t> {
let ret: i32;
asm!(
"syscall",
"test rax, rax",
"jnz 1f",
"xor ebp, ebp",
"mov rdi, r10",
"call rdx",
"1:",
in("rdx") cb,
in("r10") user_data,
in("rax") 435,
in("rdi") args as *mut clone_args,
in("rsi") mem::size_of_val(args),
lateout("eax") ret,
out("rcx") _,
out("r11") _,
);
result_from_value(ret)
}