]> git.lizzy.rs Git - rust.git/blob - tests/ui-fulldeps/issue-81357-unsound-file-methods.rs
Extend `BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE`.
[rust.git] / tests / ui-fulldeps / issue-81357-unsound-file-methods.rs
1 // run-fail
2 // only-windows
3
4 fn main() {
5     use std::fs;
6     use std::io::prelude::*;
7     use std::os::windows::prelude::*;
8     use std::ptr;
9     use std::sync::Arc;
10     use std::thread;
11     use std::time::Duration;
12
13     const FILE_FLAG_OVERLAPPED: u32 = 0x40000000;
14
15     fn create_pipe_server(path: &str) -> fs::File {
16         let mut path0 = path.as_bytes().to_owned();
17         path0.push(0);
18         extern "system" {
19             fn CreateNamedPipeA(
20                 lpName: *const u8,
21                 dwOpenMode: u32,
22                 dwPipeMode: u32,
23                 nMaxInstances: u32,
24                 nOutBufferSize: u32,
25                 nInBufferSize: u32,
26                 nDefaultTimeOut: u32,
27                 lpSecurityAttributes: *mut u8,
28             ) -> RawHandle;
29         }
30
31         unsafe {
32             let h = CreateNamedPipeA(path0.as_ptr(), 3, 0, 1, 0, 0, 0, ptr::null_mut());
33             assert_ne!(h as isize, -1);
34             fs::File::from_raw_handle(h)
35         }
36     }
37
38     let path = "\\\\.\\pipe\\repro";
39     let mut server = create_pipe_server(path);
40
41     let client = Arc::new(
42         fs::OpenOptions::new().custom_flags(FILE_FLAG_OVERLAPPED).read(true).open(path).unwrap(),
43     );
44
45     let spawn_read = |is_first: bool| {
46         thread::spawn({
47             let f = client.clone();
48             move || {
49                 let mut buf = [0xcc; 1];
50                 let mut f = f.as_ref();
51                 f.read(&mut buf).unwrap();
52                 if is_first {
53                     assert_ne!(buf[0], 0xcc);
54                 } else {
55                     let b = buf[0]; // capture buf[0]
56                     thread::sleep(Duration::from_millis(200));
57
58                     // Check the buffer hasn't been written to after read.
59                     dbg!(buf[0], b);
60                     assert_eq!(buf[0], b);
61                 }
62             }
63         })
64     };
65
66     let t1 = spawn_read(true);
67     thread::sleep(Duration::from_millis(20));
68     let t2 = spawn_read(false);
69     thread::sleep(Duration::from_millis(100));
70     let _ = server.write(b"x");
71     thread::sleep(Duration::from_millis(100));
72     let _ = server.write(b"y");
73
74     // This is run fail because we need to test for the `abort`.
75     // That failing to run is the success case.
76     if t1.join().is_err() || t2.join().is_err() {
77         return;
78     } else {
79         panic!("success");
80     }
81 }