summaryrefslogtreecommitdiff
path: root/library/std/src/sys/unix/process/process_unix.rs
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2022-12-12 09:49:42 +0100
committerRalf Jung <post@ralfj.de>2022-12-12 21:02:49 +0100
commit3465d5fb168e99fd3a16a6b525feffbeca43647e (patch)
tree7449931576fd8330f1ee4397c90347e73f04dc40 /library/std/src/sys/unix/process/process_unix.rs
parent2cd2070af7643ad88d280a4933bc4fb60451e521 (diff)
downloadrust-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.rs7
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;