diff --git a/library/std/src/sys/pal/unix/process/process_unix/tests.rs b/library/std/src/sys/pal/unix/process/process_unix/tests.rs index 6e952ed7c42..0a6c6ec19fc 100644 --- a/library/std/src/sys/pal/unix/process/process_unix/tests.rs +++ b/library/std/src/sys/pal/unix/process/process_unix/tests.rs @@ -62,13 +62,14 @@ fn test_command_fork_no_unwind() { } #[test] -#[cfg(target_os = "linux")] +#[cfg(target_os = "linux")] // pidfds are a linux-specific concept fn test_command_pidfd() { use crate::assert_matches::assert_matches; use crate::os::fd::{AsRawFd, RawFd}; use crate::os::linux::process::{ChildExt, CommandExt}; use crate::process::Command; + // pidfds require the pidfd_open syscall let our_pid = crate::process::id(); let pidfd = unsafe { libc::syscall(libc::SYS_pidfd_open, our_pid, 0) }; let pidfd_open_available = if pidfd >= 0 { @@ -81,7 +82,9 @@ fn test_command_pidfd() { // always exercise creation attempts let mut child = Command::new("false").create_pidfd(true).spawn().unwrap(); - // but only check if we know that the kernel supports pidfds + // but only check if we know that the kernel supports pidfds. + // We don't assert the precise value, since the standard library + // might have opened other file descriptors before our code runs. if pidfd_open_available { assert!(child.pidfd().is_ok()); } @@ -97,4 +100,17 @@ fn test_command_pidfd() { child.kill().expect("failed to kill child"); let status = child.wait().expect("error waiting on pidfd"); assert_eq!(status.signal(), Some(libc::SIGKILL)); + + let _ = Command::new("echo") + .create_pidfd(false) + .spawn() + .unwrap() + .pidfd() + .expect_err("pidfd should not have been created when create_pid(false) is set"); + + let _ = Command::new("echo") + .spawn() + .unwrap() + .pidfd() + .expect_err("pidfd should not have been created"); } diff --git a/tests/ui/command/command-create-pidfd.rs b/tests/ui/command/command-create-pidfd.rs deleted file mode 100644 index 9f9e5dd0e01..00000000000 --- a/tests/ui/command/command-create-pidfd.rs +++ /dev/null @@ -1,46 +0,0 @@ -// run-pass -// only-linux - pidfds are a linux-specific concept - -#![feature(linux_pidfd)] -#![feature(rustc_private)] - -extern crate libc; - -use std::io::Error; -use std::os::linux::process::{ChildExt, CommandExt}; -use std::process::Command; - -fn has_clone3() -> bool { - let res = unsafe { libc::syscall(libc::SYS_clone3, 0, 0) }; - let err = (res == -1) - .then(|| Error::last_os_error()) - .expect("probe syscall should not succeed"); - - err.raw_os_error() != Some(libc::ENOSYS) && err.raw_os_error() != Some(libc::EPERM) -} - -fn main() { - // pidfds require the clone3 syscall - if !has_clone3() { - return; - } - - // We don't assert the precise value, since the standard library - // might have opened other file descriptors before our code runs. - let _ = Command::new("echo") - .create_pidfd(true) - .spawn() - .unwrap() - .pidfd().expect("failed to obtain pidfd"); - - let _ = Command::new("echo") - .create_pidfd(false) - .spawn() - .unwrap() - .pidfd().expect_err("pidfd should not have been created when create_pid(false) is set"); - - let _ = Command::new("echo") - .spawn() - .unwrap() - .pidfd().expect_err("pidfd should not have been created"); -}