mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 15:32:06 +00:00
Tests for unsound Windows file methods
This commit is contained in:
parent
3ae47e76a8
commit
a8ffc7fd45
@ -1,5 +1,8 @@
|
||||
#![unstable(issue = "none", feature = "windows_handle")]
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use crate::cmp;
|
||||
use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, Read, ReadBuf};
|
||||
use crate::mem;
|
||||
|
22
library/std/src/sys/windows/handle/tests.rs
Normal file
22
library/std/src/sys/windows/handle/tests.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::sys::pipe::{anon_pipe, Pipes};
|
||||
use crate::{thread, time};
|
||||
|
||||
/// Test the synchronous fallback for overlapped I/O.
|
||||
#[test]
|
||||
fn overlapped_handle_fallback() {
|
||||
// Create some pipes. `ours` will be asynchronous.
|
||||
let Pipes { ours, theirs } = anon_pipe(true, false).unwrap();
|
||||
|
||||
let async_readable = ours.into_handle();
|
||||
let sync_writeable = theirs.into_handle();
|
||||
|
||||
thread::scope(|_| {
|
||||
thread::sleep(time::Duration::from_millis(100));
|
||||
sync_writeable.write(b"hello world!").unwrap();
|
||||
});
|
||||
|
||||
// The pipe buffer starts empty so reading won't complete synchronously unless
|
||||
// our fallback path works.
|
||||
let mut buffer = [0u8; 1024];
|
||||
async_readable.read(&mut buffer).unwrap();
|
||||
}
|
76
src/test/ui-fulldeps/issues-81357-unsound-file-methods.rs
Normal file
76
src/test/ui-fulldeps/issues-81357-unsound-file-methods.rs
Normal file
@ -0,0 +1,76 @@
|
||||
// run-fail
|
||||
// only-windows
|
||||
|
||||
fn main() {
|
||||
use std::fs;
|
||||
use std::io::prelude::*;
|
||||
use std::os::windows::prelude::*;
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
const FILE_FLAG_OVERLAPPED: u32 = 0x40000000;
|
||||
|
||||
fn create_pipe_server(path: &str) -> fs::File {
|
||||
let mut path0 = path.as_bytes().to_owned();
|
||||
path0.push(0);
|
||||
extern "system" {
|
||||
fn CreateNamedPipeA(
|
||||
lpName: *const u8,
|
||||
dwOpenMode: u32,
|
||||
dwPipeMode: u32,
|
||||
nMaxInstances: u32,
|
||||
nOutBufferSize: u32,
|
||||
nInBufferSize: u32,
|
||||
nDefaultTimeOut: u32,
|
||||
lpSecurityAttributes: *mut u8,
|
||||
) -> RawHandle;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let h = CreateNamedPipeA(path0.as_ptr(), 3, 0, 1, 0, 0, 0, ptr::null_mut());
|
||||
assert_ne!(h as isize, -1);
|
||||
fs::File::from_raw_handle(h)
|
||||
}
|
||||
}
|
||||
|
||||
let path = "\\\\.\\pipe\\repro";
|
||||
let mut server = create_pipe_server(path);
|
||||
|
||||
let client = Arc::new(
|
||||
fs::OpenOptions::new().custom_flags(FILE_FLAG_OVERLAPPED).read(true).open(path).unwrap(),
|
||||
);
|
||||
|
||||
let spawn_read = |is_first: bool| {
|
||||
thread::spawn({
|
||||
let f = client.clone();
|
||||
move || {
|
||||
let mut buf = [0xcc; 1];
|
||||
let mut f = f.as_ref();
|
||||
f.read(&mut buf).unwrap();
|
||||
if is_first {
|
||||
assert_ne!(buf[0], 0xcc);
|
||||
} else {
|
||||
let b = buf[0]; // capture buf[0]
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
|
||||
// In this test, success is indicated by failing.
|
||||
if buf[0] == b {
|
||||
panic!("Success!");
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
let t1 = spawn_read(true);
|
||||
thread::sleep(Duration::from_millis(20));
|
||||
let t2 = spawn_read(false);
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
let _ = server.write(b"x");
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
let _ = server.write(b"y");
|
||||
let _ = t1.join();
|
||||
let _ = t2.join();
|
||||
}
|
Loading…
Reference in New Issue
Block a user