]> git.proxmox.com Git - rustc.git/blob - src/test/ui/stdio-is-blocking.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / src / test / ui / stdio-is-blocking.rs
1 // run-pass
2 // ignore-emscripten no processes
3 // ignore-sgx no processes
4
5 use std::env;
6 use std::io::prelude::*;
7 use std::process::Command;
8 use std::thread;
9
10 const THREADS: usize = 20;
11 const WRITES: usize = 100;
12 const WRITE_SIZE: usize = 1024 * 32;
13
14 fn main() {
15 let args = env::args().collect::<Vec<_>>();
16 if args.len() == 1 {
17 parent();
18 } else {
19 child();
20 }
21 }
22
23 fn parent() {
24 let me = env::current_exe().unwrap();
25 let mut cmd = Command::new(me);
26 cmd.arg("run-the-test");
27 let output = cmd.output().unwrap();
28 assert!(output.status.success());
29 assert_eq!(output.stderr.len(), 0);
30 assert_eq!(output.stdout.len(), WRITES * THREADS * WRITE_SIZE);
31 for byte in output.stdout.iter() {
32 assert_eq!(*byte, b'a');
33 }
34 }
35
36 fn child() {
37 let threads = (0..THREADS).map(|_| {
38 thread::spawn(|| {
39 let buf = [b'a'; WRITE_SIZE];
40 for _ in 0..WRITES {
41 write_all(&buf);
42 }
43 })
44 }).collect::<Vec<_>>();
45
46 for thread in threads {
47 thread.join().unwrap();
48 }
49 }
50
51 #[cfg(unix)]
52 fn write_all(buf: &[u8]) {
53 use std::fs::File;
54 use std::mem;
55 use std::os::unix::prelude::*;
56
57 let mut file = unsafe { File::from_raw_fd(1) };
58 let res = file.write_all(buf);
59 mem::forget(file);
60 res.unwrap();
61 }
62
63 #[cfg(windows)]
64 fn write_all(buf: &[u8]) {
65 use std::fs::File;
66 use std::mem;
67 use std::os::windows::raw::*;
68 use std::os::windows::prelude::*;
69
70 const STD_OUTPUT_HANDLE: u32 = (-11i32) as u32;
71
72 extern "system" {
73 fn GetStdHandle(handle: u32) -> HANDLE;
74 }
75
76 let mut file = unsafe {
77 let handle = GetStdHandle(STD_OUTPUT_HANDLE);
78 assert!(!handle.is_null());
79 File::from_raw_handle(handle)
80 };
81 let res = file.write_all(buf);
82 mem::forget(file);
83 res.unwrap();
84 }