diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:13 +0000 |
commit | 218caa410aa38c29984be31a5229b9fa717560ee (patch) | |
tree | c54bd55eeb6e4c508940a30e94c0032fbd45d677 /src/test/ui/process | |
parent | Releasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/process')
22 files changed, 0 insertions, 1144 deletions
diff --git a/src/test/ui/process/core-run-destroy.rs b/src/test/ui/process/core-run-destroy.rs deleted file mode 100644 index d0e97bf01..000000000 --- a/src/test/ui/process/core-run-destroy.rs +++ /dev/null @@ -1,88 +0,0 @@ -// run-pass - -#![allow(unused_must_use)] -#![allow(stable_features)] -#![allow(deprecated)] -#![allow(unused_imports)] -// compile-flags:--test -// ignore-emscripten no processes -// ignore-sgx no processes -// ignore-vxworks no 'cat' and 'sleep' -// ignore-fuchsia no 'cat' - -// N.B., these tests kill child processes. Valgrind sees these children as leaking -// memory, which makes for some *confusing* logs. That's why these are here -// instead of in std. - -#![feature(rustc_private, duration)] - -extern crate libc; - -use std::process::{self, Command, Child, Output, Stdio}; -use std::str; -use std::sync::mpsc::channel; -use std::thread; -use std::time::Duration; - -macro_rules! t { - ($e:expr) => (match $e { Ok(e) => e, Err(e) => panic!("error: {}", e) }) -} - -#[test] -fn test_destroy_once() { - let mut p = sleeper(); - t!(p.kill()); -} - -#[cfg(unix)] -pub fn sleeper() -> Child { - t!(Command::new("sleep").arg("1000").spawn()) -} -#[cfg(windows)] -pub fn sleeper() -> Child { - // There's a `timeout` command on windows, but it doesn't like having - // its output piped, so instead just ping ourselves a few times with - // gaps in between so we're sure this process is alive for awhile - t!(Command::new("ping").arg("127.0.0.1").arg("-n").arg("1000").spawn()) -} - -#[test] -fn test_destroy_twice() { - let mut p = sleeper(); - t!(p.kill()); // this shouldn't crash... - let _ = p.kill(); // ...and nor should this (and nor should the destructor) -} - -#[test] -fn test_destroy_actually_kills() { - let cmd = if cfg!(windows) { - "cmd" - } else if cfg!(target_os = "android") { - "/system/bin/cat" - } else { - "cat" - }; - - // this process will stay alive indefinitely trying to read from stdin - let mut p = t!(Command::new(cmd) - .stdin(Stdio::piped()) - .spawn()); - - t!(p.kill()); - - // Don't let this test time out, this should be quick - let (tx, rx) = channel(); - thread::spawn(move|| { - thread::sleep_ms(1000); - if rx.try_recv().is_err() { - process::exit(1); - } - }); - let code = t!(p.wait()).code(); - if cfg!(windows) { - assert!(code.is_some()); - } else { - assert!(code.is_none()); - } - tx.send(()); -} diff --git a/src/test/ui/process/fds-are-cloexec.rs b/src/test/ui/process/fds-are-cloexec.rs deleted file mode 100644 index 4482b7032..000000000 --- a/src/test/ui/process/fds-are-cloexec.rs +++ /dev/null @@ -1,82 +0,0 @@ -// run-pass -// ignore-windows -// ignore-android -// ignore-emscripten no processes -// ignore-haiku -// ignore-sgx no processes - -#![feature(rustc_private)] - -extern crate libc; - -use std::env; -use std::fs::File; -use std::io; -use std::net::{TcpListener, TcpStream, UdpSocket}; -use std::os::unix::prelude::*; -use std::process::{Command, Stdio}; -use std::thread; - -fn main() { - let args = env::args().collect::<Vec<_>>(); - if args.len() == 1 { - parent() - } else { - child(&args) - } -} - -fn parent() { - let file = File::open(env::current_exe().unwrap()).unwrap(); - let tcp1 = TcpListener::bind("127.0.0.1:0").unwrap(); - let tcp2 = tcp1.try_clone().unwrap(); - let addr = tcp1.local_addr().unwrap(); - let t = thread::spawn(move || TcpStream::connect(addr).unwrap()); - let tcp3 = tcp1.accept().unwrap().0; - let tcp4 = t.join().unwrap(); - let tcp5 = tcp3.try_clone().unwrap(); - let tcp6 = tcp4.try_clone().unwrap(); - let udp1 = UdpSocket::bind("127.0.0.1:0").unwrap(); - let udp2 = udp1.try_clone().unwrap(); - - let mut child = Command::new(env::args().next().unwrap()) - .arg("100") - .stdout(Stdio::piped()) - .stdin(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn().unwrap(); - let pipe1 = child.stdin.take().unwrap(); - let pipe2 = child.stdout.take().unwrap(); - let pipe3 = child.stderr.take().unwrap(); - - - let status = Command::new(env::args().next().unwrap()) - .arg(file.as_raw_fd().to_string()) - .arg(tcp1.as_raw_fd().to_string()) - .arg(tcp2.as_raw_fd().to_string()) - .arg(tcp3.as_raw_fd().to_string()) - .arg(tcp4.as_raw_fd().to_string()) - .arg(tcp5.as_raw_fd().to_string()) - .arg(tcp6.as_raw_fd().to_string()) - .arg(udp1.as_raw_fd().to_string()) - .arg(udp2.as_raw_fd().to_string()) - .arg(pipe1.as_raw_fd().to_string()) - .arg(pipe2.as_raw_fd().to_string()) - .arg(pipe3.as_raw_fd().to_string()) - .status() - .unwrap(); - assert!(status.success()); - child.wait().unwrap(); -} - -fn child(args: &[String]) { - let mut b = [0u8; 2]; - for arg in &args[1..] { - let fd: libc::c_int = arg.parse().unwrap(); - unsafe { - assert_eq!(libc::read(fd, b.as_mut_ptr() as *mut _, 2), -1); - assert_eq!(io::Error::last_os_error().raw_os_error(), - Some(libc::EBADF)); - } - } -} diff --git a/src/test/ui/process/issue-13304.rs b/src/test/ui/process/issue-13304.rs deleted file mode 100644 index b10f6d572..000000000 --- a/src/test/ui/process/issue-13304.rs +++ /dev/null @@ -1,39 +0,0 @@ -// run-pass -#![allow(unused_mut)] -// ignore-emscripten no processes -// ignore-sgx no processes - -use std::env; -use std::io::prelude::*; -use std::io; -use std::process::{Command, Stdio}; -use std::str; - -fn main() { - let args: Vec<String> = env::args().collect(); - if args.len() > 1 && args[1] == "child" { - child(); - } else { - parent(); - } -} - -fn parent() { - let args: Vec<String> = env::args().collect(); - let mut p = Command::new(&args[0]).arg("child") - .stdout(Stdio::piped()) - .stdin(Stdio::piped()) - .spawn().unwrap(); - p.stdin.as_mut().unwrap().write_all(b"test1\ntest2\ntest3").unwrap(); - let out = p.wait_with_output().unwrap(); - assert!(out.status.success()); - let s = str::from_utf8(&out.stdout).unwrap(); - assert_eq!(s, "test1\ntest2\ntest3\n"); -} - -fn child() { - let mut stdin = io::stdin(); - for line in stdin.lock().lines() { - println!("{}", line.unwrap()); - } -} diff --git a/src/test/ui/process/issue-14456.rs b/src/test/ui/process/issue-14456.rs deleted file mode 100644 index 52a56eb77..000000000 --- a/src/test/ui/process/issue-14456.rs +++ /dev/null @@ -1,37 +0,0 @@ -// run-pass -#![allow(unused_mut)] -// ignore-emscripten no processes -// ignore-sgx no processes - -use std::env; -use std::io::prelude::*; -use std::io; -use std::process::{Command, Stdio}; - -fn main() { - let args: Vec<String> = env::args().collect(); - if args.len() > 1 && args[1] == "child" { - return child() - } - - test(); -} - -fn child() { - writeln!(&mut io::stdout(), "foo").unwrap(); - writeln!(&mut io::stderr(), "bar").unwrap(); - let mut stdin = io::stdin(); - let mut s = String::new(); - stdin.lock().read_line(&mut s).unwrap(); - assert_eq!(s.len(), 0); -} - -fn test() { - let args: Vec<String> = env::args().collect(); - let mut p = Command::new(&args[0]).arg("child") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn().unwrap(); - assert!(p.wait().unwrap().success()); -} diff --git a/src/test/ui/process/issue-14940.rs b/src/test/ui/process/issue-14940.rs deleted file mode 100644 index 98a4af0c4..000000000 --- a/src/test/ui/process/issue-14940.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass -// ignore-emscripten no processes -// ignore-sgx no processes - -use std::env; -use std::process::Command; -use std::io::{self, Write}; - -fn main() { - let mut args = env::args(); - if args.len() > 1 { - let mut out = io::stdout(); - out.write(&['a' as u8; 128 * 1024]).unwrap(); - } else { - let out = Command::new(&args.next().unwrap()).arg("child").output(); - let out = out.unwrap(); - assert!(out.status.success()); - } -} diff --git a/src/test/ui/process/issue-16272.rs b/src/test/ui/process/issue-16272.rs deleted file mode 100644 index 5cf3fd949..000000000 --- a/src/test/ui/process/issue-16272.rs +++ /dev/null @@ -1,23 +0,0 @@ -// run-pass -// ignore-emscripten no processes -// ignore-sgx no processes - -use std::process::Command; -use std::env; - -fn main() { - let len = env::args().len(); - - if len == 1 { - test(); - } else { - assert_eq!(len, 3); - } -} - -fn test() { - let status = Command::new(&env::current_exe().unwrap()) - .arg("foo").arg("") - .status().unwrap(); - assert!(status.success()); -} diff --git a/src/test/ui/process/issue-20091.rs b/src/test/ui/process/issue-20091.rs deleted file mode 100644 index 86cc79d6b..000000000 --- a/src/test/ui/process/issue-20091.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-pass -#![allow(stable_features)] - -// ignore-emscripten no processes -// ignore-sgx no processes - -#![feature(os)] - -#[cfg(unix)] -fn main() { - use std::process::Command; - use std::env; - use std::os::unix::prelude::*; - use std::ffi::OsStr; - - if env::args().len() == 1 { - assert!(Command::new(&env::current_exe().unwrap()) - .arg(<OsStr as OsStrExt>::from_bytes(b"\xff")) - .status().unwrap().success()) - } -} - -#[cfg(windows)] -fn main() {} diff --git a/src/test/ui/process/multi-panic.rs b/src/test/ui/process/multi-panic.rs deleted file mode 100644 index a1887c218..000000000 --- a/src/test/ui/process/multi-panic.rs +++ /dev/null @@ -1,38 +0,0 @@ -// run-pass -// ignore-emscripten no processes -// ignore-sgx no processes -// needs-unwind - -fn check_for_no_backtrace(test: std::process::Output) { - assert!(!test.status.success()); - let err = String::from_utf8_lossy(&test.stderr); - let mut it = err.lines(); - - assert_eq!(it.next().map(|l| l.starts_with("thread '<unnamed>' panicked at")), Some(true)); - assert_eq!(it.next(), Some("note: run with `RUST_BACKTRACE=1` \ - environment variable to display a backtrace")); - assert_eq!(it.next().map(|l| l.starts_with("thread 'main' panicked at")), Some(true)); - assert_eq!(it.next(), None); -} - -fn main() { - let args: Vec<String> = std::env::args().collect(); - if args.len() > 1 && args[1] == "run_test" { - let _ = std::thread::spawn(|| { - panic!(); - }).join(); - - panic!(); - } else { - let test = std::process::Command::new(&args[0]).arg("run_test") - .env_remove("RUST_BACKTRACE") - .output() - .unwrap(); - check_for_no_backtrace(test); - let test = std::process::Command::new(&args[0]).arg("run_test") - .env("RUST_BACKTRACE","0") - .output() - .unwrap(); - check_for_no_backtrace(test); - } -} diff --git a/src/test/ui/process/no-stdio.rs b/src/test/ui/process/no-stdio.rs deleted file mode 100644 index 24985386a..000000000 --- a/src/test/ui/process/no-stdio.rs +++ /dev/null @@ -1,139 +0,0 @@ -// run-pass -// ignore-android -// ignore-emscripten no processes -// ignore-sgx no processes -// revisions: mir thir -// [thir]compile-flags: -Zthir-unsafeck - -#![feature(rustc_private)] - -extern crate libc; - -use std::process::{Command, Stdio}; -use std::env; -use std::io::{self, Read, Write}; - -#[cfg(unix)] -unsafe fn without_stdio<R, F: FnOnce() -> R>(f: F) -> R { - let doit = |a| { - let r = libc::dup(a); - assert!(r >= 0); - return r - }; - let a = doit(0); - let b = doit(1); - let c = doit(2); - - assert!(libc::close(0) >= 0); - assert!(libc::close(1) >= 0); - assert!(libc::close(2) >= 0); - - let r = f(); - - assert!(libc::dup2(a, 0) >= 0); - assert!(libc::dup2(b, 1) >= 0); - assert!(libc::dup2(c, 2) >= 0); - - return r -} - -#[cfg(unix)] -fn assert_fd_is_valid(fd: libc::c_int) { - if unsafe { libc::fcntl(fd, libc::F_GETFD) == -1 } { - panic!("file descriptor {} is not valid: {}", fd, io::Error::last_os_error()); - } -} - -#[cfg(windows)] -fn assert_fd_is_valid(_fd: libc::c_int) {} - -#[cfg(windows)] -unsafe fn without_stdio<R, F: FnOnce() -> R>(f: F) -> R { - type DWORD = u32; - type HANDLE = *mut u8; - type BOOL = i32; - - const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD; - const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; - const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD; - const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE; - - extern "system" { - fn GetStdHandle(which: DWORD) -> HANDLE; - fn SetStdHandle(which: DWORD, handle: HANDLE) -> BOOL; - } - - let doit = |id| { - let handle = GetStdHandle(id); - assert!(handle != INVALID_HANDLE_VALUE); - assert!(SetStdHandle(id, INVALID_HANDLE_VALUE) != 0); - return handle - }; - - let a = doit(STD_INPUT_HANDLE); - let b = doit(STD_OUTPUT_HANDLE); - let c = doit(STD_ERROR_HANDLE); - - let r = f(); - - let doit = |id, handle| { - assert!(SetStdHandle(id, handle) != 0); - }; - doit(STD_INPUT_HANDLE, a); - doit(STD_OUTPUT_HANDLE, b); - doit(STD_ERROR_HANDLE, c); - - return r -} - -fn main() { - if env::args().len() > 1 { - // Writing to stdout & stderr should not panic. - println!("test"); - assert!(io::stdout().write(b"test\n").is_ok()); - assert!(io::stderr().write(b"test\n").is_ok()); - - // Stdin should be at EOF. - assert_eq!(io::stdin().read(&mut [0; 10]).unwrap(), 0); - - // Standard file descriptors should be valid on UNIX: - assert_fd_is_valid(0); - assert_fd_is_valid(1); - assert_fd_is_valid(2); - return - } - - // First, make sure reads/writes without stdio work if stdio itself is - // missing. - let (a, b, c) = unsafe { - without_stdio(|| { - let a = io::stdout().write(b"test\n"); - let b = io::stderr().write(b"test\n"); - let c = io::stdin().read(&mut [0; 10]); - - (a, b, c) - }) - }; - - assert_eq!(a.unwrap(), 5); - assert_eq!(b.unwrap(), 5); - assert_eq!(c.unwrap(), 0); - - // Second, spawn a child and do some work with "null" descriptors to make - // sure it's ok - let me = env::current_exe().unwrap(); - let status = Command::new(&me) - .arg("next") - .stdin(Stdio::null()) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status().unwrap(); - assert!(status.success(), "{} isn't a success", status); - - // Finally, close everything then spawn a child to make sure everything is - // *still* ok. - let status = unsafe { - without_stdio(|| Command::new(&me).arg("next").status()) - }.unwrap(); - assert!(status.success(), "{} isn't a success", status); -} diff --git a/src/test/ui/process/nofile-limit.rs b/src/test/ui/process/nofile-limit.rs deleted file mode 100644 index 3ddf8d6ef..000000000 --- a/src/test/ui/process/nofile-limit.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Check that statically linked binary executes successfully -// with RLIMIT_NOFILE resource lowered to zero. Regression -// test for issue #96621. -// -// run-pass -// dont-check-compiler-stderr -// only-linux -// no-prefer-dynamic -// compile-flags: -Ctarget-feature=+crt-static -Crpath=no -Crelocation-model=static -#![feature(exit_status_error)] -#![feature(rustc_private)] -extern crate libc; - -use std::os::unix::process::CommandExt; -use std::process::Command; - -fn main() { - let mut args = std::env::args(); - let this = args.next().unwrap(); - match args.next().as_deref() { - None => { - let mut cmd = Command::new(this); - cmd.arg("Ok!"); - unsafe { - cmd.pre_exec(|| { - let rlim = libc::rlimit { - rlim_cur: 0, - rlim_max: 0, - }; - if libc::setrlimit(libc::RLIMIT_NOFILE, &rlim) == -1 { - Err(std::io::Error::last_os_error()) - } else { - Ok(()) - } - }) - }; - let output = cmd.output().unwrap(); - println!("{:?}", output); - output.status.exit_ok().unwrap(); - assert!(output.stdout.starts_with(b"Ok!")); - } - Some(word) => { - println!("{}", word); - } - } -} diff --git a/src/test/ui/process/process-envs.rs b/src/test/ui/process/process-envs.rs deleted file mode 100644 index f3a469791..000000000 --- a/src/test/ui/process/process-envs.rs +++ /dev/null @@ -1,54 +0,0 @@ -// run-pass -// ignore-emscripten no processes -// ignore-sgx no processes -// ignore-vxworks no 'env' -// ignore-fuchsia no 'env' - -use std::process::Command; -use std::env; -use std::collections::HashMap; - -#[cfg(all(unix, not(target_os="android")))] -pub fn env_cmd() -> Command { - Command::new("env") -} -#[cfg(target_os="android")] -pub fn env_cmd() -> Command { - let mut cmd = Command::new("/system/bin/sh"); - cmd.arg("-c").arg("set"); - cmd -} - -#[cfg(windows)] -pub fn env_cmd() -> Command { - let mut cmd = Command::new("cmd"); - cmd.arg("/c").arg("set"); - cmd -} - -fn main() { - // save original environment - let old_env = env::var_os("RUN_TEST_NEW_ENV"); - - env::set_var("RUN_TEST_NEW_ENV", "123"); - - // create filtered environment vector - let filtered_env : HashMap<String, String> = - env::vars().filter(|&(ref k, _)| k == "PATH").collect(); - - let mut cmd = env_cmd(); - cmd.env_clear(); - cmd.envs(&filtered_env); - - // restore original environment - match old_env { - None => env::remove_var("RUN_TEST_NEW_ENV"), - Some(val) => env::set_var("RUN_TEST_NEW_ENV", &val) - } - - let result = cmd.output().unwrap(); - let output = String::from_utf8_lossy(&result.stdout); - - assert!(!output.contains("RUN_TEST_NEW_ENV"), - "found RUN_TEST_NEW_ENV inside of:\n\n{}", output); -} diff --git a/src/test/ui/process/process-exit.rs b/src/test/ui/process/process-exit.rs deleted file mode 100644 index d193e073e..000000000 --- a/src/test/ui/process/process-exit.rs +++ /dev/null @@ -1,26 +0,0 @@ -// run-pass -#![allow(unused_imports)] -// ignore-emscripten no processes -// ignore-sgx no processes - -use std::env; -use std::process::{self, Command, Stdio}; - -fn main() { - let args: Vec<String> = env::args().collect(); - if args.len() > 1 && args[1] == "child" { - child(); - } else { - parent(); - } -} - -fn parent() { - let args: Vec<String> = env::args().collect(); - let status = Command::new(&args[0]).arg("child").status().unwrap(); - assert_eq!(status.code(), Some(2)); -} - -fn child() -> i32 { - process::exit(2); -} diff --git a/src/test/ui/process/process-panic-after-fork.rs b/src/test/ui/process/process-panic-after-fork.rs deleted file mode 100644 index 6d4d24922..000000000 --- a/src/test/ui/process/process-panic-after-fork.rs +++ /dev/null @@ -1,192 +0,0 @@ -// run-pass -// no-prefer-dynamic -// ignore-wasm32-bare no libc -// ignore-windows -// ignore-sgx no libc -// ignore-emscripten no processes -// ignore-sgx no processes -// ignore-fuchsia no fork - -#![feature(rustc_private)] -#![feature(never_type)] -#![feature(panic_always_abort)] - -extern crate libc; - -use std::alloc::{GlobalAlloc, Layout}; -use std::fmt; -use std::panic::{self, panic_any}; -use std::os::unix::process::{CommandExt, ExitStatusExt}; -use std::process::{self, Command, ExitStatus}; -use std::sync::atomic::{AtomicU32, Ordering}; - -use libc::c_int; - -/// This stunt allocator allows us to spot heap allocations in the child. -struct PidChecking<A> { - parent: A, - require_pid: AtomicU32, -} - -#[global_allocator] -static ALLOCATOR: PidChecking<std::alloc::System> = PidChecking { - parent: std::alloc::System, - require_pid: AtomicU32::new(0), -}; - -impl<A> PidChecking<A> { - fn engage(&self) { - let parent_pid = process::id(); - eprintln!("engaging allocator trap, parent pid={}", parent_pid); - self.require_pid.store(parent_pid, Ordering::Release); - } - fn check(&self) { - let require_pid = self.require_pid.load(Ordering::Acquire); - if require_pid != 0 { - let actual_pid = process::id(); - if require_pid != actual_pid { - unsafe { - libc::raise(libc::SIGUSR1); - } - } - } - } -} - -unsafe impl<A:GlobalAlloc> GlobalAlloc for PidChecking<A> { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - self.check(); - self.parent.alloc(layout) - } - - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - self.check(); - self.parent.dealloc(ptr, layout) - } - - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - self.check(); - self.parent.alloc_zeroed(layout) - } - - unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - self.check(); - self.parent.realloc(ptr, layout, new_size) - } -} - -fn expect_aborted(status: ExitStatus) { - dbg!(status); - let signal = status.signal().expect("expected child process to die of signal"); - - #[cfg(not(target_os = "android"))] - assert!(signal == libc::SIGABRT || signal == libc::SIGILL || signal == libc::SIGTRAP); - - #[cfg(target_os = "android")] - { - // Android signals an abort() call with SIGSEGV at address 0xdeadbaad - // See e.g. https://groups.google.com/g/android-ndk/c/laW1CJc7Icc - assert!(signal == libc::SIGSEGV); - - // Additional checks performed: - // 1. Find last tombstone (similar to coredump but in text format) from the - // same executable (path) as we are (must be because of usage of fork): - // This ensures that we look into the correct tombstone. - // 2. Cause of crash is a SIGSEGV with address 0xdeadbaad. - // 3. libc::abort call is in one of top two functions on callstack. - // The last two steps distinguish between a normal SIGSEGV and one caused - // by libc::abort. - - let this_exe = std::env::current_exe().unwrap().into_os_string().into_string().unwrap(); - let exe_string = format!(">>> {this_exe} <<<"); - let tombstone = (0..100) - .map(|n| format!("/data/tombstones/tombstone_{n:02}")) - .filter(|f| std::path::Path::new(&f).exists()) - .map(|f| std::fs::read_to_string(&f).expect("Cannot read tombstone file")) - .filter(|f| f.contains(&exe_string)) - .last() - .expect("no tombstone found"); - - println!("Content of tombstone:\n{tombstone}"); - - assert!( - tombstone.contains("signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad") - ); - let abort_on_top = tombstone - .lines() - .skip_while(|l| !l.contains("backtrace:")) - .skip(1) - .take_while(|l| l.starts_with(" #")) - .take(2) - .any(|f| f.contains("/system/lib/libc.so (abort")); - assert!(abort_on_top); - } -} - -fn main() { - ALLOCATOR.engage(); - - fn run(do_panic: &dyn Fn()) -> ExitStatus { - let child = unsafe { libc::fork() }; - assert!(child >= 0); - if child == 0 { - panic::always_abort(); - do_panic(); - process::exit(0); - } - let mut status: c_int = 0; - let got = unsafe { libc::waitpid(child, &mut status, 0) }; - assert_eq!(got, child); - let status = ExitStatus::from_raw(status.into()); - status - } - - fn one(do_panic: &dyn Fn()) { - let status = run(do_panic); - expect_aborted(status); - } - - one(&|| panic!()); - one(&|| panic!("some message")); - one(&|| panic!("message with argument: {}", 42)); - - #[derive(Debug)] - struct Wotsit { } - one(&|| panic_any(Wotsit { })); - - let mut c = Command::new("echo"); - unsafe { - c.pre_exec(|| panic!("{}", "crash now!")); - } - let st = c.status().expect("failed to get command status"); - expect_aborted(st); - - struct DisplayWithHeap; - impl fmt::Display for DisplayWithHeap { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - let s = vec![0; 100]; - let s = std::hint::black_box(s); - write!(f, "{:?}", s) - } - } - - // Some panics in the stdlib that we want not to allocate, as - // otherwise these facilities become impossible to use in the - // child after fork, which is really quite awkward. - - one(&|| { None::<DisplayWithHeap>.unwrap(); }); - one(&|| { None::<DisplayWithHeap>.expect("unwrapped a none"); }); - one(&|| { std::str::from_utf8(b"\xff").unwrap(); }); - one(&|| { - let x = [0, 1, 2, 3]; - let y = x[std::hint::black_box(4)]; - let _z = std::hint::black_box(y); - }); - - // Finally, check that our stunt allocator can actually catch an allocation after fork. - // ie, that our test is effective. - - let status = run(&|| panic!("allocating to display... {}", DisplayWithHeap)); - dbg!(status); - assert_eq!(status.signal(), Some(libc::SIGUSR1)); -} diff --git a/src/test/ui/process/process-remove-from-env.rs b/src/test/ui/process/process-remove-from-env.rs deleted file mode 100644 index ad027d685..000000000 --- a/src/test/ui/process/process-remove-from-env.rs +++ /dev/null @@ -1,48 +0,0 @@ -// run-pass -// ignore-emscripten no processes -// ignore-sgx no processes -// ignore-vxworks no 'env' -// ignore-fuchsia no 'env' - -use std::process::Command; -use std::env; - -#[cfg(all(unix, not(target_os="android")))] -pub fn env_cmd() -> Command { - Command::new("env") -} -#[cfg(target_os="android")] -pub fn env_cmd() -> Command { - let mut cmd = Command::new("/system/bin/sh"); - cmd.arg("-c").arg("set"); - cmd -} - -#[cfg(windows)] -pub fn env_cmd() -> Command { - let mut cmd = Command::new("cmd"); - cmd.arg("/c").arg("set"); - cmd -} - -fn main() { - // save original environment - let old_env = env::var_os("RUN_TEST_NEW_ENV"); - - env::set_var("RUN_TEST_NEW_ENV", "123"); - - let mut cmd = env_cmd(); - cmd.env_remove("RUN_TEST_NEW_ENV"); - - // restore original environment - match old_env { - None => env::remove_var("RUN_TEST_NEW_ENV"), - Some(val) => env::set_var("RUN_TEST_NEW_ENV", &val) - } - - let result = cmd.output().unwrap(); - let output = String::from_utf8_lossy(&result.stdout); - - assert!(!output.contains("RUN_TEST_NEW_ENV"), - "found RUN_TEST_NEW_ENV inside of:\n\n{}", output); -} diff --git a/src/test/ui/process/process-sigpipe.rs b/src/test/ui/process/process-sigpipe.rs deleted file mode 100644 index 107eba45d..000000000 --- a/src/test/ui/process/process-sigpipe.rs +++ /dev/null @@ -1,37 +0,0 @@ -// run-pass -#![allow(unused_imports)] -#![allow(deprecated)] - -// ignore-android since the dynamic linker sets a SIGPIPE handler (to do -// a crash report) so inheritance is moot on the entire platform - -// libstd ignores SIGPIPE, and other libraries may set signal masks. -// Make sure that these behaviors don't get inherited to children -// spawned via std::process, since they're needed for traditional UNIX -// filter behavior. This test checks that `yes | head` terminates -// (instead of running forever), and that it does not print an error -// message about a broken pipe. - -// ignore-emscripten no threads support -// ignore-vxworks no 'sh' -// ignore-fuchsia no 'sh' - -use std::process; -use std::thread; - -#[cfg(unix)] -fn main() { - // Just in case `yes` doesn't check for EPIPE... - thread::spawn(|| { - thread::sleep_ms(5000); - process::exit(1); - }); - let output = process::Command::new("sh").arg("-c").arg("yes | head").output().unwrap(); - assert!(output.status.success()); - assert!(output.stderr.len() == 0); -} - -#[cfg(not(unix))] -fn main() { - // Not worried about signal masks on other platforms -} diff --git a/src/test/ui/process/process-spawn-nonexistent.rs b/src/test/ui/process/process-spawn-nonexistent.rs deleted file mode 100644 index 9dd608986..000000000 --- a/src/test/ui/process/process-spawn-nonexistent.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-pass -// ignore-emscripten no processes -// ignore-sgx no processes -// ignore-fuchsia ErrorKind not translated - -use std::io::ErrorKind; -use std::process::Command; - -fn main() { - let result = Command::new("nonexistent").spawn().unwrap_err().kind(); - - assert!(matches!( - result, - // Under WSL with appendWindowsPath=true, this fails with PermissionDenied - ErrorKind::NotFound | ErrorKind::PermissionDenied - )); -} diff --git a/src/test/ui/process/process-spawn-with-unicode-params.rs b/src/test/ui/process/process-spawn-with-unicode-params.rs deleted file mode 100644 index 16dba6292..000000000 --- a/src/test/ui/process/process-spawn-with-unicode-params.rs +++ /dev/null @@ -1,77 +0,0 @@ -// run-pass -// no-prefer-dynamic - -// The test copies itself into a subdirectory with a non-ASCII name and then -// runs it as a child process within the subdirectory. The parent process -// also adds an environment variable and an argument, both containing -// non-ASCII characters. The child process ensures all the strings are -// intact. - -// ignore-emscripten no processes -// ignore-sgx no processes -// ignore-fuchsia Filesystem manipulation privileged - -use std::io::prelude::*; -use std::io; -use std::fs; -use std::process::Command; -use std::env; -use std::path::Path; - -fn main() { - let my_args = env::args().collect::<Vec<_>>(); - let my_cwd = env::current_dir().unwrap(); - let my_env = env::vars().collect::<Vec<_>>(); - let my_path = env::current_exe().unwrap(); - let my_dir = my_path.parent().unwrap(); - let my_ext = my_path.extension().and_then(|s| s.to_str()).unwrap_or(""); - - // some non-ASCII characters - let blah = "\u{3c0}\u{42f}\u{97f3}\u{e6}\u{221e}"; - - let child_name = "child"; - let child_dir = format!("process-spawn-with-unicode-params-{}", blah); - - // parameters sent to child / expected to be received from parent - let arg = blah; - let cwd = my_dir.join(&child_dir); - let env = ("RUST_TEST_PROC_SPAWN_UNICODE".to_string(), blah.to_string()); - - // am I the parent or the child? - if my_args.len() == 1 { // parent - - let child_filestem = Path::new(child_name); - let child_filename = child_filestem.with_extension(my_ext); - let child_path = cwd.join(&child_filename); - - // make a separate directory for the child - let _ = fs::create_dir(&cwd); - fs::copy(&my_path, &child_path).unwrap(); - - // run child - let p = Command::new(&child_path) - .arg(arg) - .current_dir(&cwd) - .env(&env.0, &env.1) - .spawn().unwrap().wait_with_output().unwrap(); - - // display the output - io::stdout().write_all(&p.stdout).unwrap(); - io::stderr().write_all(&p.stderr).unwrap(); - - // make sure the child succeeded - assert!(p.status.success()); - - } else { // child - - // check working directory (don't try to compare with `cwd` here!) - assert!(my_cwd.ends_with(&child_dir)); - - // check arguments - assert_eq!(&*my_args[1], arg); - - // check environment variable - assert!(my_env.contains(&env)); - - }; -} diff --git a/src/test/ui/process/process-status-inherits-stdin.rs b/src/test/ui/process/process-status-inherits-stdin.rs deleted file mode 100644 index 7719dd9ad..000000000 --- a/src/test/ui/process/process-status-inherits-stdin.rs +++ /dev/null @@ -1,35 +0,0 @@ -// run-pass -// ignore-emscripten no processes -// ignore-sgx no processes - -use std::env; -use std::io; -use std::io::Write; -use std::process::{Command, Stdio}; - -fn main() { - let mut args = env::args(); - let me = args.next().unwrap(); - let arg = args.next(); - match arg.as_ref().map(|s| &s[..]) { - None => { - let mut s = Command::new(&me) - .arg("a1") - .stdin(Stdio::piped()) - .spawn() - .unwrap(); - s.stdin.take().unwrap().write_all(b"foo\n").unwrap(); - let s = s.wait().unwrap(); - assert!(s.success()); - } - Some("a1") => { - let s = Command::new(&me).arg("a2").status().unwrap(); - assert!(s.success()); - } - Some(..) => { - let mut s = String::new(); - io::stdin().read_line(&mut s).unwrap(); - assert_eq!(s, "foo\n"); - } - } -} diff --git a/src/test/ui/process/signal-exit-status.rs b/src/test/ui/process/signal-exit-status.rs deleted file mode 100644 index 9519ed7b4..000000000 --- a/src/test/ui/process/signal-exit-status.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass -// ignore-emscripten no processes -// ignore-sgx no processes -// ignore-windows -// ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#58590) - -use std::env; -use std::process::Command; - -pub fn main() { - let args: Vec<String> = env::args().collect(); - if args.len() >= 2 && args[1] == "signal" { - // Raise a segfault. - unsafe { *(1 as *mut isize) = 0; } - } else { - let status = Command::new(&args[0]).arg("signal").status().unwrap(); - assert!(status.code().is_none()); - } -} diff --git a/src/test/ui/process/sigpipe-should-be-ignored.rs b/src/test/ui/process/sigpipe-should-be-ignored.rs deleted file mode 100644 index 144eeca23..000000000 --- a/src/test/ui/process/sigpipe-should-be-ignored.rs +++ /dev/null @@ -1,33 +0,0 @@ -// run-pass - -#![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-emscripten no processes -// ignore-sgx no processes - -use std::env; -use std::io::prelude::*; -use std::io; -use std::process::{Command, Stdio}; - -fn test() { - let _ = io::stdin().read_line(&mut String::new()); - io::stdout().write(&[1]); - assert!(io::stdout().flush().is_err()); -} - -fn main() { - let args: Vec<String> = env::args().collect(); - if args.len() > 1 && args[1] == "test" { - return test(); - } - - let mut p = Command::new(&args[0]) - .stdout(Stdio::piped()) - .stdin(Stdio::piped()) - .arg("test").spawn().unwrap(); - drop(p.stdout.take()); - assert!(p.wait().unwrap().success()); -} diff --git a/src/test/ui/process/tls-exit-status.rs b/src/test/ui/process/tls-exit-status.rs deleted file mode 100644 index 6296e5042..000000000 --- a/src/test/ui/process/tls-exit-status.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-fail -// error-pattern:nonzero -// exec-env:RUST_NEWRT=1 -// ignore-emscripten no processes - -use std::env; - -fn main() { - env::args(); - panic!("please have a nonzero exit status"); -} diff --git a/src/test/ui/process/try-wait.rs b/src/test/ui/process/try-wait.rs deleted file mode 100644 index 692197210..000000000 --- a/src/test/ui/process/try-wait.rs +++ /dev/null @@ -1,60 +0,0 @@ -// run-pass - -#![allow(stable_features)] -// ignore-emscripten no processes -// ignore-sgx no processes - -#![feature(process_try_wait)] - -use std::env; -use std::process::Command; -use std::thread; -use std::time::Duration; - -fn main() { - let args = env::args().collect::<Vec<_>>(); - if args.len() != 1 { - match &args[1][..] { - "sleep" => thread::sleep(Duration::new(1_000, 0)), - _ => {} - } - return - } - - let mut me = Command::new(env::current_exe().unwrap()) - .arg("sleep") - .spawn() - .unwrap(); - let maybe_status = me.try_wait().unwrap(); - assert!(maybe_status.is_none()); - let maybe_status = me.try_wait().unwrap(); - assert!(maybe_status.is_none()); - - me.kill().unwrap(); - me.wait().unwrap(); - - let status = me.try_wait().unwrap().unwrap(); - assert!(!status.success()); - let status = me.try_wait().unwrap().unwrap(); - assert!(!status.success()); - - let mut me = Command::new(env::current_exe().unwrap()) - .arg("return-quickly") - .spawn() - .unwrap(); - loop { - match me.try_wait() { - Ok(Some(res)) => { - assert!(res.success()); - break - } - Ok(None) => { - thread::sleep(Duration::from_millis(1)); - } - Err(e) => panic!("error in try_wait: {}", e), - } - } - - let status = me.try_wait().unwrap().unwrap(); - assert!(status.success()); -} |