Skip to content

Commit

Permalink
Simplify Command::spawn (no semantic change)
Browse files Browse the repository at this point in the history
This minimizes the size of an unsafe block, and allows outdenting some
complex code.
  • Loading branch information
joshtriplett committed Mar 29, 2021
1 parent 2917eda commit 68dbdfb
Showing 1 changed file with 27 additions and 33 deletions.
60 changes: 27 additions & 33 deletions library/std/src/sys/unix/process/process_unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,41 +51,35 @@ impl Command {
// 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.
let (env_lock, result) = unsafe { (sys::os::env_read_lock(), cvt(libc::fork())?) };

let pid = unsafe {
match result {
0 => {
mem::forget(env_lock);
drop(input);
let Err(err) = self.do_exec(theirs, envp.as_ref());
let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
let errno = errno.to_be_bytes();
let bytes = [
errno[0],
errno[1],
errno[2],
errno[3],
CLOEXEC_MSG_FOOTER[0],
CLOEXEC_MSG_FOOTER[1],
CLOEXEC_MSG_FOOTER[2],
CLOEXEC_MSG_FOOTER[3],
];
// pipe I/O up to PIPE_BUF bytes should be atomic, and then
// we want to be sure we *don't* run at_exit destructors as
// we're being torn down regardless
rtassert!(output.write(&bytes).is_ok());
libc::_exit(1)
}
n => {
drop(env_lock);
n
}
}
};
let (env_lock, pid) = unsafe { (sys::os::env_read_lock(), cvt(libc::fork())?) };

let mut p = Process { pid, status: None };
if pid == 0 {
mem::forget(env_lock);
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;
let errno = errno.to_be_bytes();
let bytes = [
errno[0],
errno[1],
errno[2],
errno[3],
CLOEXEC_MSG_FOOTER[0],
CLOEXEC_MSG_FOOTER[1],
CLOEXEC_MSG_FOOTER[2],
CLOEXEC_MSG_FOOTER[3],
];
// pipe I/O up to PIPE_BUF bytes should be atomic, and then
// we want to be sure we *don't* run at_exit destructors as
// we're being torn down regardless
rtassert!(output.write(&bytes).is_ok());
unsafe { libc::_exit(1) }
}

drop(env_lock);
drop(output);

let mut p = Process { pid, status: None };
let mut bytes = [0; 8];

// loop to handle EINTR
Expand Down

0 comments on commit 68dbdfb

Please sign in to comment.