diff options
author | Ralf Jung <post@ralfj.de> | 2022-12-12 09:49:42 +0100 |
---|---|---|
committer | Ralf Jung <post@ralfj.de> | 2022-12-12 21:02:49 +0100 |
commit | 3465d5fb168e99fd3a16a6b525feffbeca43647e (patch) | |
tree | 7449931576fd8330f1ee4397c90347e73f04dc40 /library/std/src/sys/unix/process/process_unix.rs | |
parent | 2cd2070af7643ad88d280a4933bc4fb60451e521 (diff) | |
download | rust-3465d5fb168e99fd3a16a6b525feffbeca43647e.tar.gz |
explain mem::forget(env_lock) in fork/exec
Diffstat (limited to 'library/std/src/sys/unix/process/process_unix.rs')
-rw-r--r-- | library/std/src/sys/unix/process/process_unix.rs | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 56a805cef73..c0716a089bc 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -66,14 +66,15 @@ impl Command { // // Note that as soon as we're done with the fork there's no need to hold // a lock any more because the parent won't do anything and the child is - // in its own process. Thus the parent drops the lock guard while the child - // forgets it to avoid unlocking it on a new thread, which would be invalid. + // in its own process. Thus the parent drops the lock guard immediately. + // The child calls `mem::forget` to leak the lock, which is crucial because + // releasing a lock is not async-signal-safe. let env_lock = sys::os::env_read_lock(); let (pid, pidfd) = unsafe { self.do_fork()? }; if pid == 0 { crate::panic::always_abort(); - mem::forget(env_lock); + mem::forget(env_lock); // avoid non-async-signal-safe unlocking drop(input); let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) }; let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32; |