Skip to content

outcome of Command::status changes depending on whether posix_spawn or execvp is used internally #160933

Description

@japaric

I tried this:

$ rm -f /tmp/empty
$ touch /tmp/empty
$ chmod 0555 /tmp/empty
$ cargo new --bin hello
$ cd hello
$ $EDITOR src/main.rs
$ cat src/main.rs
use std::process::Command;
fn main() {
    _ = dbg!(Command::new("/tmp/empty").status());
}
  • On Ubuntu 20.04
$ ldd --version | head -n1
ldd (Ubuntu GLIBC 2.31-0ubuntu9.17) 2.31

$ cargo run
[src/main.rs:3:9] Command::new("/tmp/empty").status() = Err(
    Os {
        code: 8,
        kind: Uncategorized,
        message: "Exec format error",
    },
)
  • On Centos 7
$ ldd --version | head -n1
ldd (GNU libc) 2.17

$ cargo run
[src/main.rs:3:9] Command::new("/tmp/empty").status() = Ok(
    ExitStatus(
        unix_wait_status(
            0,
        ),
    ),
)

I expected to see this happen: the same behavior regardless of the glibc version.

Instead, this happened: whether you get an error or success depends on the system libc version

Meta

rustc --version --verbose:

binary: rustc
commit-hash: 12c36e2539c54397c51d6ea4401defd8768a4f5b
commit-date: 2026-08-10
host: x86_64-unknown-linux-gnu
release: 1.99.0-nightly
LLVM version: 23.1.0

Investigation

AFAICT, the difference is due to Command::spawn using libc::posix_spawn on GLIBC 2.24 and newer; and execvp older GLIBC versions 1. the posix_spawn logic produces the Err outcome; the execvp logic produces the Ok outcome

patching libstd to never take the posix_spawn lets me reproduce the Ok outcome on Ubuntu 22.04 (glibc 2.35)

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions