Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions library/std/src/os/unix/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,10 @@ pub trait ChildExt: Sealed {
/// use libc::SIGTERM;
///
/// fn main() -> io::Result<()> {
/// # if cfg!(not(all(target_vendor = "apple", not(target_os = "macos")))) {
/// let child = Command::new("cat").stdin(Stdio::piped()).spawn()?;
/// child.send_signal(SIGTERM)?;
/// # }
/// Ok(())
/// }
/// ```
Expand Down
16 changes: 9 additions & 7 deletions library/std/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ impl fmt::Debug for ChildStderr {
/// to be changed (for example, by adding arguments) prior to spawning:
///
/// ```
/// # if cfg!(not(all(target_vendor = "apple", not(target_os = "macos")))) {
/// use std::process::Command;
///
/// let output = if cfg!(target_os = "windows") {
Expand All @@ -548,6 +549,7 @@ impl fmt::Debug for ChildStderr {
/// };
///
/// let hello = output.stdout;
/// # }
/// ```
///
/// `Command` can be reused to spawn multiple processes. The builder methods
Expand Down Expand Up @@ -1348,7 +1350,7 @@ impl Output {
///
/// ```
/// #![feature(exit_status_error)]
/// # #[cfg(all(unix, not(target_os = "android")))] {
/// # #[cfg(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos")))))] {
/// use std::process::Command;
/// assert!(Command::new("false").output().unwrap().exit_ok().is_err());
/// # }
Expand Down Expand Up @@ -1695,7 +1697,7 @@ impl From<io::Stdout> for Stdio {
/// # Ok(())
/// # }
/// #
/// # if cfg!(all(unix, not(target_os = "android"))) {
/// # if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) {
/// # test().unwrap();
/// # }
/// ```
Expand Down Expand Up @@ -1724,7 +1726,7 @@ impl From<io::Stderr> for Stdio {
/// # Ok(())
/// # }
/// #
/// # if cfg!(all(unix, not(target_os = "android"))) {
/// # if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) {
/// # test().unwrap();
/// # }
/// ```
Expand Down Expand Up @@ -1800,7 +1802,7 @@ impl ExitStatus {
///
/// ```
/// #![feature(exit_status_error)]
/// # if cfg!(unix) {
/// # if cfg!(all(unix, not(all(target_vendor = "apple", not(target_os = "macos"))))) {
/// use std::process::Command;
///
/// let status = Command::new("ls")
Expand Down Expand Up @@ -1907,7 +1909,7 @@ impl crate::sealed::Sealed for ExitStatusError {}
///
/// ```
/// #![feature(exit_status_error)]
/// # if cfg!(all(unix, not(target_os = "android"))) {
/// # if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) {
/// use std::process::{Command, ExitStatusError};
///
/// fn run(cmd: &str) -> Result<(), ExitStatusError> {
Expand Down Expand Up @@ -1950,7 +1952,7 @@ impl ExitStatusError {
///
/// ```
/// #![feature(exit_status_error)]
/// # #[cfg(all(unix, not(target_os = "android")))] {
/// # #[cfg(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos")))))] {
/// use std::process::Command;
///
/// let bad = Command::new("false").status().unwrap().exit_ok().unwrap_err();
Expand All @@ -1975,7 +1977,7 @@ impl ExitStatusError {
/// ```
/// #![feature(exit_status_error)]
///
/// # if cfg!(all(unix, not(target_os = "android"))) {
/// # if cfg!(all(unix, not(target_os = "android"), not(all(target_vendor = "apple", not(target_os = "macos"))))) {
/// use std::num::NonZero;
/// use std::process::Command;
///
Expand Down
102 changes: 83 additions & 19 deletions library/std/src/process/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ use crate::mem::MaybeUninit;
use crate::str;

fn known_command() -> Command {
if cfg!(windows) { Command::new("help") } else { Command::new("echo") }
if cfg!(windows) {
Command::new("help")
} else if cfg!(all(target_vendor = "apple", not(target_os = "macos"))) {
// iOS/tvOS/watchOS/visionOS have a very limited set of commandline
// binaries available.
Command::new("log")
} else {
Command::new("echo")
}
}

#[cfg(target_os = "android")]
Expand All @@ -19,7 +27,10 @@ fn shell_cmd() -> Command {
}

#[test]
#[cfg_attr(any(target_os = "vxworks"), ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn smoke() {
let p = if cfg!(target_os = "windows") {
Command::new("cmd").args(&["/C", "exit 0"]).spawn()
Expand All @@ -41,7 +52,10 @@ fn smoke_failure() {
}

#[test]
#[cfg_attr(any(target_os = "vxworks"), ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn exit_reported_right() {
let p = if cfg!(target_os = "windows") {
Command::new("cmd").args(&["/C", "exit 1"]).spawn()
Expand All @@ -56,7 +70,10 @@ fn exit_reported_right() {

#[test]
#[cfg(unix)]
#[cfg_attr(any(target_os = "vxworks"), ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn signal_reported_right() {
use crate::os::unix::process::ExitStatusExt;

Expand All @@ -80,7 +97,10 @@ pub fn run_output(mut cmd: Command) -> String {
}

#[test]
#[cfg_attr(any(target_os = "vxworks"), ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn stdout_works() {
if cfg!(target_os = "windows") {
let mut cmd = Command::new("cmd");
Expand All @@ -94,7 +114,11 @@ fn stdout_works() {
}

#[test]
#[cfg_attr(any(windows, target_os = "vxworks"), ignore)]
#[cfg_attr(windows, ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn set_current_dir_works() {
// On many Unix platforms this will use the posix_spawn path.
let mut cmd = shell_cmd();
Expand All @@ -116,7 +140,11 @@ fn set_current_dir_works() {
}

#[test]
#[cfg_attr(any(windows, target_os = "vxworks"), ignore)]
#[cfg_attr(windows, ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn stdin_works() {
let mut p = shell_cmd()
.arg("-c")
Expand All @@ -134,7 +162,10 @@ fn stdin_works() {
}

#[test]
#[cfg_attr(any(target_os = "vxworks"), ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn child_stdout_read_buf() {
let mut cmd = if cfg!(target_os = "windows") {
let mut cmd = Command::new("cmd");
Expand Down Expand Up @@ -165,7 +196,10 @@ fn child_stdout_read_buf() {
}

#[test]
#[cfg_attr(any(target_os = "vxworks"), ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn test_process_status() {
let mut status = if cfg!(target_os = "windows") {
Command::new("cmd").args(&["/C", "exit 1"]).status().unwrap()
Expand All @@ -191,7 +225,10 @@ fn test_process_output_fail_to_start() {
}

#[test]
#[cfg_attr(any(target_os = "vxworks"), ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn test_process_output_output() {
let Output { status, stdout, stderr } = if cfg!(target_os = "windows") {
Command::new("cmd").args(&["/C", "echo hello"]).output().unwrap()
Expand All @@ -206,7 +243,10 @@ fn test_process_output_output() {
}

#[test]
#[cfg_attr(any(target_os = "vxworks"), ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn test_process_output_error() {
let Output { status, stdout, stderr } = if cfg!(target_os = "windows") {
Command::new("cmd").args(&["/C", "mkdir ."]).output().unwrap()
Expand All @@ -221,7 +261,10 @@ fn test_process_output_error() {
}

#[test]
#[cfg_attr(any(target_os = "vxworks"), ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn test_finish_once() {
let mut prog = if cfg!(target_os = "windows") {
Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
Expand All @@ -232,7 +275,10 @@ fn test_finish_once() {
}

#[test]
#[cfg_attr(any(target_os = "vxworks"), ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn test_finish_twice() {
let mut prog = if cfg!(target_os = "windows") {
Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
Expand All @@ -244,7 +290,10 @@ fn test_finish_twice() {
}

#[test]
#[cfg_attr(any(target_os = "vxworks"), ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn test_wait_with_output_once() {
let prog = if cfg!(target_os = "windows") {
Command::new("cmd").args(&["/C", "echo hello"]).stdout(Stdio::piped()).spawn().unwrap()
Expand Down Expand Up @@ -279,7 +328,10 @@ pub fn env_cmd() -> Command {
}

#[test]
#[cfg_attr(target_os = "vxworks", ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn test_override_env() {
use crate::env;

Expand All @@ -302,7 +354,10 @@ fn test_override_env() {
}

#[test]
#[cfg_attr(target_os = "vxworks", ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn test_add_to_env() {
let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap();
let output = String::from_utf8_lossy(&result.stdout).to_string();
Expand All @@ -314,7 +369,10 @@ fn test_add_to_env() {
}

#[test]
#[cfg_attr(target_os = "vxworks", ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no shell available"
)]
fn test_capture_env_at_spawn() {
use crate::env;

Expand Down Expand Up @@ -378,7 +436,10 @@ fn test_interior_nul_in_current_dir_is_error() {

// Regression tests for #30862.
#[test]
#[cfg_attr(target_os = "vxworks", ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no `env` cmd available"
)]
fn test_interior_nul_in_env_key_is_error() {
match env_cmd().env("has-some-\0\0s-inside", "value").spawn() {
Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
Expand All @@ -387,7 +448,10 @@ fn test_interior_nul_in_env_key_is_error() {
}

#[test]
#[cfg_attr(target_os = "vxworks", ignore)]
#[cfg_attr(
any(target_os = "vxworks", all(target_vendor = "apple", not(target_os = "macos"))),
ignore = "no `env` cmd available"
)]
fn test_interior_nul_in_env_value_is_error() {
match env_cmd().env("key", "has-some-\0\0s-inside").spawn() {
Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
Expand Down
1 change: 1 addition & 0 deletions library/std/src/sys/process/unix/unix/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ fn exitstatus_display_tests() {

#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
#[cfg_attr(any(target_os = "tvos", target_os = "watchos"), ignore = "fork is prohibited")]
fn test_command_fork_no_unwind() {
let got = catch_unwind(|| {
let mut c = Command::new("echo");
Expand Down
1 change: 1 addition & 0 deletions library/std/tests/process_spawning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod common;
#[test]
// Process spawning not supported by Miri, Emscripten and wasi
#[cfg_attr(any(miri, target_os = "emscripten", target_os = "wasi"), ignore)]
#[cfg_attr(any(target_os = "tvos", target_os = "watchos"), ignore = "fork is prohibited")]
fn issue_15149() {
// If we're the parent, copy our own binary to a new directory.
let my_path = env::current_exe().unwrap();
Expand Down
31 changes: 28 additions & 3 deletions src/doc/rustc-dev-guide/src/tests/running.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,34 @@ results. The Docker image is set up to launch `remote-test-server` and the
build tools use `remote-test-client` to communicate with the server to
coordinate running tests (see [src/bootstrap/src/core/build_steps/test.rs]).

> **TODO**
>
> - Is there any support for using an iOS emulator?
To run on the iOS/tvOS/watchOS/visionOS simulator, we can similarly treat it as
a "remote" machine. A curious detail here is that the network is shared between
the simulator instance and the host macOS, so we can use the local loopback
address `127.0.0.1`. Something like the following should work:

```sh
# Build the test server for the iOS simulator:
./x build src/tools/remote-test-server --target aarch64-apple-ios-sim

# If you already have a simulator instance open, copy the device UUID from:
xcrun simctl list devices booted
UDID=01234567-89AB-CDEF-0123-456789ABCDEF

# Alternatively, create and boot a new simulator instance:
xcrun simctl list runtimes
xcrun simctl list devicetypes
UDID=$(xcrun simctl create $CHOSEN_DEVICE_TYPE $CHOSEN_RUNTIME)
xcrun simctl boot $UDID
# See https://nshipster.com/simctl/ for details.

# Spawn the runner on port 12345:
xcrun simctl spawn $UDID ./build/host/stage2-tools/aarch64-apple-ios-sim/release/remote-test-server -v --bind 127.0.0.1:12345

# In a new terminal, run tests via the runner:
export TEST_DEVICE_ADDR="127.0.0.1:12345"
./x test --host='' --target aarch64-apple-ios-sim --skip tests/debuginfo
# FIXME(madsmtm): Allow debuginfo tests to work (maybe needs `.dSYM` folder to be copied to the target?).
```

[armhf-gnu]: https://github.com/rust-lang/rust/tree/master/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
[QEMU]: https://www.qemu.org/
Expand Down
Loading
Loading