summaryrefslogtreecommitdiffstats
path: root/src/test/ui/process
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /src/test/ui/process
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-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')
-rw-r--r--src/test/ui/process/core-run-destroy.rs88
-rw-r--r--src/test/ui/process/fds-are-cloexec.rs82
-rw-r--r--src/test/ui/process/issue-13304.rs39
-rw-r--r--src/test/ui/process/issue-14456.rs37
-rw-r--r--src/test/ui/process/issue-14940.rs19
-rw-r--r--src/test/ui/process/issue-16272.rs23
-rw-r--r--src/test/ui/process/issue-20091.rs24
-rw-r--r--src/test/ui/process/multi-panic.rs38
-rw-r--r--src/test/ui/process/no-stdio.rs139
-rw-r--r--src/test/ui/process/nofile-limit.rs46
-rw-r--r--src/test/ui/process/process-envs.rs54
-rw-r--r--src/test/ui/process/process-exit.rs26
-rw-r--r--src/test/ui/process/process-panic-after-fork.rs192
-rw-r--r--src/test/ui/process/process-remove-from-env.rs48
-rw-r--r--src/test/ui/process/process-sigpipe.rs37
-rw-r--r--src/test/ui/process/process-spawn-nonexistent.rs17
-rw-r--r--src/test/ui/process/process-spawn-with-unicode-params.rs77
-rw-r--r--src/test/ui/process/process-status-inherits-stdin.rs35
-rw-r--r--src/test/ui/process/signal-exit-status.rs19
-rw-r--r--src/test/ui/process/sigpipe-should-be-ignored.rs33
-rw-r--r--src/test/ui/process/tls-exit-status.rs11
-rw-r--r--src/test/ui/process/try-wait.rs60
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());
-}