in reverie-ptrace/src/trace/memory.rs [214:251]
fn fork_helper<P, C, T>(mut value: T, parent: P, child: C) -> bool
where
P: FnOnce(Pid, T) -> bool,
C: FnOnce(&mut T),
{
match unsafe { fork() }.unwrap() {
ForkResult::Parent { child, .. } => {
assert_eq!(
waitpid(child, None).unwrap(),
WaitStatus::Stopped(child, Signal::SIGTRAP)
);
let result = parent(child.into(), value);
// Allow child to exit.
ptrace::cont(child, None).unwrap();
assert_eq!(waitpid(child, None).unwrap(), WaitStatus::Exited(child, 0));
result
}
ForkResult::Child => {
ptrace::traceme().unwrap();
// Give us a chance to modify if needed.
child(&mut value);
// Allow parent to control when we exit. While stopped here, the
// parent can mess with the child's memory.
raise(Signal::SIGTRAP).unwrap();
// Can't use the normal exit function here because we don't want
// to call atexit handlers since `execve` was never called.
unsafe {
::libc::_exit(0);
}
}
}
}