diff options
| author | kennytm <kennytm@gmail.com> | 2019-02-16 00:55:56 +0800 |
|---|---|---|
| committer | kennytm <kennytm@gmail.com> | 2019-02-16 14:11:47 +0800 |
| commit | 50f3c81c0ecb875d45ac25a771c1bb3c61ff9eba (patch) | |
| tree | 8559a9a55a2fc5d09bcc1a005815e2c5454cdc08 /src/libstd/sys | |
| parent | 0fecb6d97d0b548a2b3d23f30f384b13d4a9251e (diff) | |
| parent | a301655c8aed20e5cea9a062663820fc29c5e80c (diff) | |
| download | rust-50f3c81c0ecb875d45ac25a771c1bb3c61ff9eba.tar.gz rust-50f3c81c0ecb875d45ac25a771c1bb3c61ff9eba.zip | |
Rollup merge of #58438 - cuviper:posix_spawn_file_actions_addchdir_np, r=alexcrichton
Use posix_spawn_file_actions_addchdir_np when possible 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()`.
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/unix/process/process_unix.rs | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 12d3e9b13b1..6fbbbb349b1 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -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 { @@ -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); @@ -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))?; |
