diff options
Diffstat (limited to 'tests/ui/process')
27 files changed, 202 insertions, 66 deletions
diff --git a/tests/ui/process/core-run-destroy.rs b/tests/ui/process/core-run-destroy.rs index 3f2ea0e8441..b4815c9dfbb 100644 --- a/tests/ui/process/core-run-destroy.rs +++ b/tests/ui/process/core-run-destroy.rs @@ -1,12 +1,11 @@ //@ run-pass #![allow(unused_must_use)] -#![allow(stable_features)] #![allow(deprecated)] #![allow(unused_imports)] + //@ compile-flags:--test -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess //@ ignore-vxworks no 'cat' and 'sleep' //@ ignore-fuchsia no 'cat' diff --git a/tests/ui/process/env-args-reverse-iterator.rs b/tests/ui/process/env-args-reverse-iterator.rs index 830e9535466..f0afeeb22eb 100644 --- a/tests/ui/process/env-args-reverse-iterator.rs +++ b/tests/ui/process/env-args-reverse-iterator.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess use std::env::args; use std::process::Command; diff --git a/tests/ui/process/fds-are-cloexec.rs b/tests/ui/process/fds-are-cloexec.rs index e7b000b2c49..f6678379dd6 100644 --- a/tests/ui/process/fds-are-cloexec.rs +++ b/tests/ui/process/fds-are-cloexec.rs @@ -1,9 +1,8 @@ //@ run-pass -//@ ignore-windows +//@ only-unix //@ ignore-android -//@ ignore-wasm32 no processes +//@ needs-subprocess //@ ignore-haiku -//@ ignore-sgx no processes #![feature(rustc_private)] diff --git a/tests/ui/process/inherit-env.rs b/tests/ui/process/inherit-env.rs index 0eb61fcdd53..09d5b76141e 100644 --- a/tests/ui/process/inherit-env.rs +++ b/tests/ui/process/inherit-env.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ ignore-wasm32 no subprocess support -//@ ignore-sgx no processes +//@ needs-subprocess use std::env; use std::process::Command; diff --git a/tests/ui/process/issue-13304.rs b/tests/ui/process/issue-13304.rs index 6dbf0caaaec..621c54300d3 100644 --- a/tests/ui/process/issue-13304.rs +++ b/tests/ui/process/issue-13304.rs @@ -1,7 +1,5 @@ //@ run-pass -#![allow(unused_mut)] -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess use std::env; use std::io::prelude::*; @@ -32,7 +30,7 @@ fn parent() { } fn child() { - let mut stdin = io::stdin(); + let stdin = io::stdin(); for line in stdin.lock().lines() { println!("{}", line.unwrap()); } diff --git a/tests/ui/process/issue-14456.rs b/tests/ui/process/issue-14456.rs index fd6da8a5fc4..e67a9d8bad5 100644 --- a/tests/ui/process/issue-14456.rs +++ b/tests/ui/process/issue-14456.rs @@ -1,7 +1,5 @@ //@ run-pass -#![allow(unused_mut)] -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess use std::env; use std::io::prelude::*; @@ -20,7 +18,7 @@ fn main() { fn child() { writeln!(&mut io::stdout(), "foo").unwrap(); writeln!(&mut io::stderr(), "bar").unwrap(); - let mut stdin = io::stdin(); + let stdin = io::stdin(); let mut s = String::new(); stdin.lock().read_line(&mut s).unwrap(); assert_eq!(s.len(), 0); diff --git a/tests/ui/process/issue-14940.rs b/tests/ui/process/issue-14940.rs index 13fb18154a0..cfbc743250f 100644 --- a/tests/ui/process/issue-14940.rs +++ b/tests/ui/process/issue-14940.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess use std::env; use std::process::Command; diff --git a/tests/ui/process/issue-16272.rs b/tests/ui/process/issue-16272.rs index bf26769d494..72708554753 100644 --- a/tests/ui/process/issue-16272.rs +++ b/tests/ui/process/issue-16272.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess use std::process::Command; use std::env; diff --git a/tests/ui/process/issue-20091.rs b/tests/ui/process/issue-20091.rs index b6d94661b75..72bf4c0e71e 100644 --- a/tests/ui/process/issue-20091.rs +++ b/tests/ui/process/issue-20091.rs @@ -1,9 +1,5 @@ //@ run-pass -#![allow(stable_features)] -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes - -#![feature(os)] +//@ needs-subprocess #[cfg(unix)] fn main() { diff --git a/tests/ui/process/issue-30490.rs b/tests/ui/process/issue-30490.rs index 0d918bc3dd5..75b36e7c20b 100644 --- a/tests/ui/process/issue-30490.rs +++ b/tests/ui/process/issue-30490.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ ignore-emscripten no processes -//@ ignore-sgx no processes +//@ needs-subprocess //@ ignore-fuchsia Child I/O swaps not privileged // Previously libstd would set stdio descriptors of a child process diff --git a/tests/ui/process/multi-panic.rs b/tests/ui/process/multi-panic.rs index ad47925a149..481fe75c731 100644 --- a/tests/ui/process/multi-panic.rs +++ b/tests/ui/process/multi-panic.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess //@ needs-unwind fn check_for_no_backtrace(test: std::process::Output) { diff --git a/tests/ui/process/no-stdio.rs b/tests/ui/process/no-stdio.rs index 8eebf6dbc7d..5cc7cacbb22 100644 --- a/tests/ui/process/no-stdio.rs +++ b/tests/ui/process/no-stdio.rs @@ -1,7 +1,6 @@ //@ run-pass //@ ignore-android -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess #![feature(rustc_private)] diff --git a/tests/ui/process/println-with-broken-pipe.rs b/tests/ui/process/println-with-broken-pipe.rs index d88c6dcc12b..fbac9b6cd95 100644 --- a/tests/ui/process/println-with-broken-pipe.rs +++ b/tests/ui/process/println-with-broken-pipe.rs @@ -1,7 +1,7 @@ //@ run-pass //@ check-run-results +//@ needs-subprocess //@ ignore-windows -//@ ignore-wasm32 //@ ignore-fuchsia //@ ignore-horizon //@ ignore-android diff --git a/tests/ui/process/process-envs.rs b/tests/ui/process/process-envs.rs index 15285960d16..98052f1d3a5 100644 --- a/tests/ui/process/process-envs.rs +++ b/tests/ui/process/process-envs.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess //@ ignore-vxworks no 'env' //@ ignore-fuchsia no 'env' diff --git a/tests/ui/process/process-exit.rs b/tests/ui/process/process-exit.rs index a75a7306cbc..a1ed243b62b 100644 --- a/tests/ui/process/process-exit.rs +++ b/tests/ui/process/process-exit.rs @@ -1,10 +1,8 @@ //@ run-pass -#![allow(unused_imports)] -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess use std::env; -use std::process::{self, Command, Stdio}; +use std::process::{self, Command}; fn main() { let args: Vec<String> = env::args().collect(); diff --git a/tests/ui/process/process-panic-after-fork.rs b/tests/ui/process/process-panic-after-fork.rs index afb1b721182..6e0267e0a54 100644 --- a/tests/ui/process/process-panic-after-fork.rs +++ b/tests/ui/process/process-panic-after-fork.rs @@ -1,8 +1,7 @@ //@ run-pass //@ no-prefer-dynamic -//@ ignore-windows -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ only-unix +//@ needs-subprocess //@ ignore-fuchsia no fork #![feature(rustc_private)] diff --git a/tests/ui/process/process-remove-from-env.rs b/tests/ui/process/process-remove-from-env.rs index 21fff4fd45d..c1a2b2daf5b 100644 --- a/tests/ui/process/process-remove-from-env.rs +++ b/tests/ui/process/process-remove-from-env.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess //@ ignore-vxworks no 'env' //@ ignore-fuchsia no 'env' diff --git a/tests/ui/process/process-sigpipe.rs b/tests/ui/process/process-sigpipe.rs index 9db130c26bd..453e53379fc 100644 --- a/tests/ui/process/process-sigpipe.rs +++ b/tests/ui/process/process-sigpipe.rs @@ -15,7 +15,7 @@ //@ ignore-vxworks no 'sh' //@ ignore-fuchsia no 'sh' -//@ ignore-emscripten No threads +//@ needs-threads //@ only-unix SIGPIPE is a unix feature use std::process; diff --git a/tests/ui/process/process-spawn-nonexistent.rs b/tests/ui/process/process-spawn-nonexistent.rs index 1cd32866299..3db670624fb 100644 --- a/tests/ui/process/process-spawn-nonexistent.rs +++ b/tests/ui/process/process-spawn-nonexistent.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess //@ ignore-fuchsia ErrorKind not translated use std::io::ErrorKind; diff --git a/tests/ui/process/process-spawn-with-unicode-params.rs b/tests/ui/process/process-spawn-with-unicode-params.rs index 4d2ba49eeac..65f835c1345 100644 --- a/tests/ui/process/process-spawn-with-unicode-params.rs +++ b/tests/ui/process/process-spawn-with-unicode-params.rs @@ -7,8 +7,7 @@ // non-ASCII characters. The child process ensures all the strings are // intact. -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess //@ ignore-fuchsia Filesystem manipulation privileged use std::io::prelude::*; diff --git a/tests/ui/process/process-status-inherits-stdin.rs b/tests/ui/process/process-status-inherits-stdin.rs index 39eef34c5f8..d5dd0e55fa3 100644 --- a/tests/ui/process/process-status-inherits-stdin.rs +++ b/tests/ui/process/process-status-inherits-stdin.rs @@ -1,6 +1,5 @@ //@ run-pass -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes +//@ needs-subprocess use std::env; use std::io; diff --git a/tests/ui/process/signal-exit-status.rs b/tests/ui/process/signal-exit-status.rs index a6acea47636..33aa83abfc3 100644 --- a/tests/ui/process/signal-exit-status.rs +++ b/tests/ui/process/signal-exit-status.rs @@ -1,7 +1,6 @@ //@ run-pass -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes -//@ ignore-windows +//@ needs-subprocess +//@ only-unix (`code()` returns `None` if terminated by a signal on Unix) //@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#58590) #![feature(core_intrinsics)] diff --git a/tests/ui/process/sigpipe-should-be-ignored.rs b/tests/ui/process/sigpipe-should-be-ignored.rs index 44785bee7f8..3dcf0117ae9 100644 --- a/tests/ui/process/sigpipe-should-be-ignored.rs +++ b/tests/ui/process/sigpipe-should-be-ignored.rs @@ -1,12 +1,9 @@ //@ run-pass +//@ needs-subprocess -#![allow(unused_must_use)] // Be sure that when a SIGPIPE would have been received that the entire process // doesn't die in a ball of fire, but rather it's gracefully handled. -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes - use std::env; use std::io::prelude::*; use std::io; @@ -14,7 +11,7 @@ use std::process::{Command, Stdio}; fn test() { let _ = io::stdin().read_line(&mut String::new()); - io::stdout().write(&[1]); + io::stdout().write(&[1]).unwrap(); assert!(io::stdout().flush().is_err()); } diff --git a/tests/ui/process/tls-exit-status.rs b/tests/ui/process/tls-exit-status.rs index cddcf369da0..6dd0d71ef35 100644 --- a/tests/ui/process/tls-exit-status.rs +++ b/tests/ui/process/tls-exit-status.rs @@ -1,7 +1,7 @@ //@ run-fail //@ error-pattern:nonzero //@ exec-env:RUST_NEWRT=1 -//@ ignore-wasm32 no processes +//@ needs-subprocess use std::env; diff --git a/tests/ui/process/try-wait.rs b/tests/ui/process/try-wait.rs index b6d026d802f..dcef43ad348 100644 --- a/tests/ui/process/try-wait.rs +++ b/tests/ui/process/try-wait.rs @@ -1,9 +1,5 @@ //@ run-pass - -#![allow(stable_features)] -//@ ignore-wasm32 no processes -//@ ignore-sgx no processes -#![feature(process_try_wait)] +//@ needs-subprocess use std::env; use std::process::Command; diff --git a/tests/ui/process/win-creation-flags.rs b/tests/ui/process/win-creation-flags.rs new file mode 100644 index 00000000000..0c7c6883d68 --- /dev/null +++ b/tests/ui/process/win-creation-flags.rs @@ -0,0 +1,51 @@ +// Test that windows `creation_flags` extension to `Command` works. + +//@ run-pass +//@ only-windows +//@ needs-subprocess + +use std::env; +use std::os::windows::process::CommandExt; +use std::process::{Command, exit}; + +fn main() { + if env::args().skip(1).any(|s| s == "--child") { + child(); + } else { + parent(); + } +} + +fn parent() { + let exe = env::current_exe().unwrap(); + + // Use the DETACH_PROCESS to create a subprocess that isn't attached to the console. + // The subprocess's exit status will be 0 if it's detached. + let status = Command::new(&exe) + .arg("--child") + .creation_flags(DETACH_PROCESS) + .spawn() + .unwrap() + .wait() + .unwrap(); + assert_eq!(status.code(), Some(0)); + + // Try without DETACH_PROCESS to ensure this test works. + let status = Command::new(&exe).arg("--child").spawn().unwrap().wait().unwrap(); + assert_eq!(status.code(), Some(1)); +} + +// exits with 1 if the console is attached or 0 otherwise +fn child() { + // Get the attached console's code page. + // This will fail (return 0) if no console is attached. + let has_console = GetConsoleCP() != 0; + exit(has_console as i32); +} + +// Windows API definitions. +const DETACH_PROCESS: u32 = 0x00000008; +#[link(name = "kernel32")] +unsafe extern "system" { + safe fn GetConsoleCP() -> u32; +} diff --git a/tests/ui/process/win-proc-thread-attributes.rs b/tests/ui/process/win-proc-thread-attributes.rs new file mode 100644 index 00000000000..91bb0b17e95 --- /dev/null +++ b/tests/ui/process/win-proc-thread-attributes.rs @@ -0,0 +1,118 @@ +// Tests proc thread attributes by spawning a process with a custom parent process, +// then comparing the parent process ID with the expected parent process ID. + +//@ run-pass +//@ only-windows +//@ needs-subprocess +//@ edition: 2021 + +#![feature(windows_process_extensions_raw_attribute)] + +use std::os::windows::io::AsRawHandle; +use std::os::windows::process::{CommandExt, ProcThreadAttributeList}; +use std::process::{Child, Command}; +use std::{env, mem, ptr, thread, time}; + +// Make a best effort to ensure child processes always exit. +struct ProcessDropGuard(Child); +impl Drop for ProcessDropGuard { + fn drop(&mut self) { + let _ = self.0.kill(); + } +} + +fn main() { + if env::args().skip(1).any(|s| s == "--child") { + child(); + } else { + parent(); + } +} + +fn parent() { + let exe = env::current_exe().unwrap(); + + let (fake_parent_id, child_parent_id) = { + // Create a process to be our fake parent process. + let fake_parent = Command::new(&exe).arg("--child").spawn().unwrap(); + let fake_parent = ProcessDropGuard(fake_parent); + let parent_handle = fake_parent.0.as_raw_handle(); + + // Create another process with the parent process set to the fake. + let mut attribute_list = ProcThreadAttributeList::build() + .attribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parent_handle) + .finish() + .unwrap(); + let child = + Command::new(&exe).arg("--child").spawn_with_attributes(&mut attribute_list).unwrap(); + let child = ProcessDropGuard(child); + + // Return the fake's process id and the child's parent's id. + (process_info(&fake_parent.0).process_id(), process_info(&child.0).parent_id()) + }; + + assert_eq!(fake_parent_id, child_parent_id); +} + +// A process that stays running until killed. +fn child() { + // Don't wait forever if something goes wrong. + thread::sleep(time::Duration::from_secs(60)); +} + +fn process_info(child: &Child) -> PROCESS_BASIC_INFORMATION { + unsafe { + let mut info: PROCESS_BASIC_INFORMATION = mem::zeroed(); + let result = NtQueryInformationProcess( + child.as_raw_handle(), + ProcessBasicInformation, + ptr::from_mut(&mut info).cast(), + mem::size_of_val(&info).try_into().unwrap(), + ptr::null_mut(), + ); + assert_eq!(result, 0); + info + } +} + +// Windows API +mod winapi { + #![allow(nonstandard_style)] + use std::ffi::c_void; + + pub type HANDLE = *mut c_void; + type NTSTATUS = i32; + type PROCESSINFOCLASS = i32; + + pub const ProcessBasicInformation: i32 = 0; + pub const PROC_THREAD_ATTRIBUTE_PARENT_PROCESS: usize = 0x00020000; + #[repr(C)] + pub struct PROCESS_BASIC_INFORMATION { + pub ExitStatus: NTSTATUS, + pub PebBaseAddress: *mut (), + pub AffinityMask: usize, + pub BasePriority: i32, + pub UniqueProcessId: usize, + pub InheritedFromUniqueProcessId: usize, + } + impl PROCESS_BASIC_INFORMATION { + pub fn parent_id(&self) -> usize { + self.InheritedFromUniqueProcessId + } + pub fn process_id(&self) -> usize { + self.UniqueProcessId + } + } + + #[link(name = "ntdll")] + extern "system" { + pub fn NtQueryInformationProcess( + ProcessHandle: HANDLE, + ProcessInformationClass: PROCESSINFOCLASS, + ProcessInformation: *mut c_void, + ProcessInformationLength: u32, + ReturnLength: *mut u32, + ) -> NTSTATUS; + } +} +use winapi::*; |
