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