Skip to content

Commit

Permalink
Use posix_spawn_file_actions_addchdir_np when possible
Browse files Browse the repository at this point in the history
This is a non-POSIX extension implemented in Solaris and in glibc 2.29.
With this we can still use `posix_spawn()` when `Command::current_dir()`
has been set, otherwise we fallback to `fork(); chdir(); exec()`.
  • Loading branch information
cuviper committed Feb 13, 2019
1 parent 0f949c2 commit a301655
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions src/libstd/sys/unix/process/process_unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,7 @@ impl Command {
use mem;
use sys;

if self.get_cwd().is_some() ||
self.get_gid().is_some() ||
if self.get_gid().is_some() ||
self.get_uid().is_some() ||
self.env_saw_path() ||
self.get_closures().len() != 0 {
Expand All @@ -301,6 +300,24 @@ impl Command {
}
}

// Solaris and glibc 2.29+ can set a new working directory, and maybe
// others will gain this non-POSIX function too. We'll check for this
// weak symbol as soon as it's needed, so we can return early otherwise
// to do a manual chdir before exec.
weak! {
fn posix_spawn_file_actions_addchdir_np(
*mut libc::posix_spawn_file_actions_t,
*const libc::c_char
) -> libc::c_int
}
let addchdir = match self.get_cwd() {
Some(cwd) => match posix_spawn_file_actions_addchdir_np.get() {
Some(f) => Some((f, cwd)),
None => return Ok(None),
},
None => None,
};

let mut p = Process { pid: 0, status: None };

struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t);
Expand Down Expand Up @@ -345,6 +362,9 @@ impl Command {
fd,
libc::STDERR_FILENO))?;
}
if let Some((f, cwd)) = addchdir {
cvt(f(&mut file_actions.0, cwd.as_ptr()))?;
}

let mut set: libc::sigset_t = mem::uninitialized();
cvt(libc::sigemptyset(&mut set))?;
Expand Down

0 comments on commit a301655

Please sign in to comment.