Skip to content

Commit 57897da

Browse files
authored
Rollup merge of rust-lang#88828 - FabianWolff:issue-88585, r=dtolnay
Use `libc::sigaction()` instead of `sys::signal()` to prevent a deadlock Fixes rust-lang#88585. POSIX [specifies](https://man7.org/linux/man-pages/man3/fork.3p.html) that after forking, > to avoid errors, the child process may only execute async-signal-safe operations until such time as one of the exec functions is called. Rust's standard library does not currently adhere to this, as evidenced by rust-lang#88585. The child process calls [`sys::signal()`](https://github.com/rust-lang/rust/blob/7bf0736e130e2203c58654f7353dbf9575e49d5c/library/std/src/sys/unix/android.rs#L76), which on Android calls [`libc::dlsym()`](https://github.com/rust-lang/rust/blob/7bf0736e130e2203c58654f7353dbf9575e49d5c/library/std/src/sys/unix/weak.rs#L101), which is [**not**](https://man7.org/linux/man-pages/man7/signal-safety.7.html) async-signal-safe, and in fact causes a deadlock in the example in rust-lang#88585. I think the easiest solution here would be to just call `libc::sigaction()` instead, which [is](https://man7.org/linux/man-pages/man7/signal-safety.7.html) async-signal-safe, provides the functionality we need, and is apparently available on all Android versions because it is also used e.g. [here](https://github.com/rust-lang/rust/blob/7bf0736e130e2203c58654f7353dbf9575e49d5c/library/std/src/sys/unix/stack_overflow.rs#L112-L114).
2 parents c65a1ea + e3e5ae9 commit 57897da

File tree

1 file changed

+3
-4
lines changed

1 file changed

+3
-4
lines changed

library/std/src/sys/unix/process/process_unix.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,9 @@ impl Command {
333333
let mut set = MaybeUninit::<libc::sigset_t>::uninit();
334334
cvt(sigemptyset(set.as_mut_ptr()))?;
335335
cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), ptr::null_mut()))?;
336-
let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
337-
if ret == libc::SIG_ERR {
338-
return Err(io::Error::last_os_error());
339-
}
336+
let mut action: libc::sigaction = mem::zeroed();
337+
action.sa_sigaction = libc::SIG_DFL;
338+
cvt(libc::sigaction(libc::SIGPIPE, &action, ptr::null_mut()))?;
340339
}
341340

342341
for callback in self.get_closures().iter_mut() {

0 commit comments

Comments
 (0)