diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-12-14 17:17:57 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-14 17:17:57 +0100 |
| commit | 6d3a93c82342ee7bbf0b6f90570207bd48653229 (patch) | |
| tree | 07e6b954ce6cbd71dc4af67a217a03a64f098c06 | |
| parent | ba71a63fde087b5bddd71bc13b95cee4b71da8e2 (diff) | |
| parent | 3465d5fb168e99fd3a16a6b525feffbeca43647e (diff) | |
| download | rust-6d3a93c82342ee7bbf0b6f90570207bd48653229.tar.gz rust-6d3a93c82342ee7bbf0b6f90570207bd48653229.zip | |
Rollup merge of #105598 - RalfJung:more-comments, r=the8472
explain mem::forget(env_lock) in fork/exec I stumbled upon this while doing triage for https://github.com/rust-lang/rust/issues/64718.
| -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; |
