diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2025-02-08 21:37:24 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-08 21:37:24 +0100 |
| commit | 02b8bea0849f982a480d80487b376204f658942b (patch) | |
| tree | 75d253c22c5cfbf9b3ae5ed287cfa9a5a2a9030b /library/std/src/sys/pal/windows/io.rs | |
| parent | 8ad2c9724d983cfb116baab0bb800edd17f31644 (diff) | |
| parent | 7433ba62b10126b0ae8b78d711f19402db663101 (diff) | |
| download | rust-02b8bea0849f982a480d80487b376204f658942b.tar.gz rust-02b8bea0849f982a480d80487b376204f658942b.zip | |
Rollup merge of #135696 - joboet:move_pal_io, r=Noratrieb
std: move `io` module out of `pal`, get rid of `sys_common::io` Part of #117276. This does two related things: 1. It moves the platform-specific definitions for `IoSlice`, `IoSliceMut` and `is_terminal` out of `pal` and into `sys` and unifies some of them. 2. It gets rid of `sys_common::io`, moving the non-platform-specific test helpers into `std::test_helpers` and the buffer size definition to the new `sys::io` module.
Diffstat (limited to 'library/std/src/sys/pal/windows/io.rs')
| -rw-r--r-- | library/std/src/sys/pal/windows/io.rs | 153 |
1 files changed, 0 insertions, 153 deletions
diff --git a/library/std/src/sys/pal/windows/io.rs b/library/std/src/sys/pal/windows/io.rs deleted file mode 100644 index f2865d2ffc1..00000000000 --- a/library/std/src/sys/pal/windows/io.rs +++ /dev/null @@ -1,153 +0,0 @@ -use core::ffi::c_void; - -use crate::marker::PhantomData; -use crate::mem::size_of; -use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle}; -use crate::slice; -use crate::sys::c; - -#[derive(Copy, Clone)] -#[repr(transparent)] -pub struct IoSlice<'a> { - vec: c::WSABUF, - _p: PhantomData<&'a [u8]>, -} - -impl<'a> IoSlice<'a> { - #[inline] - pub fn new(buf: &'a [u8]) -> IoSlice<'a> { - assert!(buf.len() <= u32::MAX as usize); - IoSlice { - vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_ptr() as *mut u8 }, - _p: PhantomData, - } - } - - #[inline] - pub fn advance(&mut self, n: usize) { - if (self.vec.len as usize) < n { - panic!("advancing IoSlice beyond its length"); - } - - unsafe { - self.vec.len -= n as u32; - self.vec.buf = self.vec.buf.add(n); - } - } - - #[inline] - pub const fn as_slice(&self) -> &'a [u8] { - unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) } - } -} - -#[repr(transparent)] -pub struct IoSliceMut<'a> { - vec: c::WSABUF, - _p: PhantomData<&'a mut [u8]>, -} - -impl<'a> IoSliceMut<'a> { - #[inline] - pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { - assert!(buf.len() <= u32::MAX as usize); - IoSliceMut { - vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_mut_ptr() }, - _p: PhantomData, - } - } - - #[inline] - pub fn advance(&mut self, n: usize) { - if (self.vec.len as usize) < n { - panic!("advancing IoSliceMut beyond its length"); - } - - unsafe { - self.vec.len -= n as u32; - self.vec.buf = self.vec.buf.add(n); - } - } - - #[inline] - pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) } - } - - #[inline] - pub const fn into_slice(self) -> &'a mut [u8] { - unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) } - } - - #[inline] - pub fn as_mut_slice(&mut self) -> &mut [u8] { - unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) } - } -} - -pub fn is_terminal(h: &impl AsHandle) -> bool { - handle_is_console(h.as_handle()) -} - -fn handle_is_console(handle: BorrowedHandle<'_>) -> bool { - // A null handle means the process has no console. - if handle.as_raw_handle().is_null() { - return false; - } - - let mut out = 0; - if unsafe { c::GetConsoleMode(handle.as_raw_handle(), &mut out) != 0 } { - // False positives aren't possible. If we got a console then we definitely have a console. - return true; - } - - // Otherwise, we fall back to an msys hack to see if we can detect the presence of a pty. - msys_tty_on(handle) -} - -fn msys_tty_on(handle: BorrowedHandle<'_>) -> bool { - // Early return if the handle is not a pipe. - if unsafe { c::GetFileType(handle.as_raw_handle()) != c::FILE_TYPE_PIPE } { - return false; - } - - /// Mirrors [`FILE_NAME_INFO`], giving it a fixed length that we can stack - /// allocate - /// - /// [`FILE_NAME_INFO`]: https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_name_info - #[repr(C)] - #[allow(non_snake_case)] - struct FILE_NAME_INFO { - FileNameLength: u32, - FileName: [u16; c::MAX_PATH as usize], - } - let mut name_info = FILE_NAME_INFO { FileNameLength: 0, FileName: [0; c::MAX_PATH as usize] }; - // Safety: buffer length is fixed. - let res = unsafe { - c::GetFileInformationByHandleEx( - handle.as_raw_handle(), - c::FileNameInfo, - (&raw mut name_info) as *mut c_void, - size_of::<FILE_NAME_INFO>() as u32, - ) - }; - if res == 0 { - return false; - } - - // Use `get` because `FileNameLength` can be out of range. - let s = match name_info.FileName.get(..name_info.FileNameLength as usize / 2) { - None => return false, - Some(s) => s, - }; - let name = String::from_utf16_lossy(s); - // Get the file name only. - let name = name.rsplit('\\').next().unwrap_or(&name); - // This checks whether 'pty' exists in the file name, which indicates that - // a pseudo-terminal is attached. To mitigate against false positives - // (e.g., an actual file name that contains 'pty'), we also require that - // the file name begins with either the strings 'msys-' or 'cygwin-'.) - let is_msys = name.starts_with("msys-") || name.starts_with("cygwin-"); - let is_pty = name.contains("-pty"); - is_msys && is_pty -} |
