about summary refs log tree commit diff
path: root/library/std/src/process
diff options
context:
space:
mode:
authorRain <rain@sunshowers.io>2024-10-17 12:38:32 -0700
committerRain <rain@sunshowers.io>2024-10-23 22:11:55 -0700
commit7f74c894b0e31f370b5321d94f2ca2830e1d30fd (patch)
treece00de5233bba499071b738595ea65ac53cd476b /library/std/src/process
parentb8bb2968ce1e44d01520c9d59ee6299ed66df3f9 (diff)
downloadrust-7f74c894b0e31f370b5321d94f2ca2830e1d30fd.tar.gz
rust-7f74c894b0e31f370b5321d94f2ca2830e1d30fd.zip
[musl] use posix_spawn if a directory change was requested
Currently, not all libcs have the `posix_spawn_file_actions_addchdir_np` symbol
available to them. So we attempt to do a weak symbol lookup for that function.
But that only works if libc is a dynamic library -- with statically linked musl
binaries the symbol lookup would never work, so we would never be able to use it
even if the musl in use supported the symbol.

Now that Rust has a minimum musl version of 1.2.3, all supported musl versions
now include this symbol, so we can unconditionally expect it to be there. This
symbol was added to libc in https://github.com/rust-lang/libc/pull/3949 -- use
it here.

I couldn't find any tests for whether the posix_spawn path is used, but I've
verified with cargo-nextest that this change works. This is a substantial
improvement to nextest's performance with musl. On my workstation with a Ryzen
7950x, against https://github.com/clap-rs/clap at
61f5ee514f8f60ed8f04c6494bdf36c19e7a8126:

Before:

```
     Summary [   1.071s] 879 tests run: 879 passed, 0 skipped
```

After:

```
     Summary [   0.392s] 879 tests run: 879 passed, 0 skipped
```

Fixes #99740.
Diffstat (limited to 'library/std/src/process')
-rw-r--r--library/std/src/process/tests.rs14
1 files changed, 14 insertions, 0 deletions
diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs
index 88cc95caf40..fb0b495961c 100644
--- a/library/std/src/process/tests.rs
+++ b/library/std/src/process/tests.rs
@@ -96,9 +96,23 @@ fn stdout_works() {
 #[test]
 #[cfg_attr(any(windows, target_os = "vxworks"), ignore)]
 fn set_current_dir_works() {
+    // On many Unix platforms this will use the posix_spawn path.
     let mut cmd = shell_cmd();
     cmd.arg("-c").arg("pwd").current_dir("/").stdout(Stdio::piped());
     assert_eq!(run_output(cmd), "/\n");
+
+    // Also test the fork/exec path by setting a pre_exec function.
+    #[cfg(unix)]
+    {
+        use crate::os::unix::process::CommandExt;
+
+        let mut cmd = shell_cmd();
+        cmd.arg("-c").arg("pwd").current_dir("/").stdout(Stdio::piped());
+        unsafe {
+            cmd.pre_exec(|| Ok(()));
+        }
+        assert_eq!(run_output(cmd), "/\n");
+    }
 }
 
 #[test]