diff options
| author | tv <tv@krebsco.de> | 2026-10-21 14:14:15 +0200 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-21 14:14:15 +0200 |
| commit | f0e37237004188e761da9730e24b11fc162bec8b (patch) | |
| tree | 9733e97f6a3c4364eb4f47c4eeffe1de6d132afe /src/transport/mycelium.rs | |
| parent | a1fd8370f48956dc6084fb9c1e13e5b79ffd5fa9 (diff) | |
let linux signal supervised mycelium when we die
Diffstat (limited to 'src/transport/mycelium.rs')
| -rw-r--r-- | src/transport/mycelium.rs | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/src/transport/mycelium.rs b/src/transport/mycelium.rs index 3a08b76..d31925d 100644 --- a/src/transport/mycelium.rs +++ b/src/transport/mycelium.rs @@ -269,15 +269,29 @@ impl SupervisedMycelium { let mut cmd = Command::new("mycelium"); let fds_to_inherit: Vec<i32> = [node_fd, net_fd].iter().filter_map(|&x| x).collect(); - if !fds_to_inherit.is_empty() { - unsafe { - cmd.pre_exec(move || { - for &fd in &fds_to_inherit { - libc::fcntl(fd, libc::F_SETFD, 0); + // The child must never outlive us. An orphaned Mycelium keeps running with our + // key; the next one we start then shares its address, and replies (including + // Mycelium's own message ACKs) go to whichever instance the routers picked, + // leaving our messages pending forever. Drop only runs on a clean shutdown, so + // let the kernel signal the child when we die, however we die. + let parent_pid = std::process::id() as libc::pid_t; + unsafe { + cmd.pre_exec(move || { + for &fd in &fds_to_inherit { + libc::fcntl(fd, libc::F_SETFD, 0); + } + #[cfg(target_os = "linux")] + { + if libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGTERM) != 0 { + return Err(std::io::Error::last_os_error()); } - Ok(()) - }); - } + // We may have died between fork and prctl. + if libc::getppid() != parent_pid { + libc::_exit(1); + } + } + Ok(()) + }); } cmd.arg("--key-file") |
