mirror of
https://github.com/wez/wezterm.git
synced 2024-09-11 14:25:57 +03:00
add FileDescriptor::set_non_blocking
This commit is contained in:
parent
55b4a08131
commit
08b0017c16
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "filedescriptor"
|
name = "filedescriptor"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
authors = ["Wez Furlong"]
|
authors = ["Wez Furlong"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
repository = "https://github.com/wez/wzsh"
|
repository = "https://github.com/wez/wzsh"
|
||||||
|
@ -247,6 +247,16 @@ impl FileDescriptor {
|
|||||||
pub fn as_stdio(&self) -> anyhow::Result<std::process::Stdio> {
|
pub fn as_stdio(&self) -> anyhow::Result<std::process::Stdio> {
|
||||||
self.as_stdio_impl()
|
self.as_stdio_impl()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempt to change the non-blocking IO mode of the file descriptor.
|
||||||
|
/// Not all kinds of file descriptor can be placed in non-blocking mode
|
||||||
|
/// on all systems, and some file descriptors will claim to be in
|
||||||
|
/// non-blocking mode but it will have no effect.
|
||||||
|
/// File descriptors based on sockets are the most portable type
|
||||||
|
/// that can be successfully made non-blocking.
|
||||||
|
pub fn set_non_blocking(&mut self, non_blocking: bool) -> anyhow::Result<()> {
|
||||||
|
self.set_non_blocking_impl(non_blocking)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the readable and writable ends of a pair of descriptors
|
/// Represents the readable and writable ends of a pair of descriptors
|
||||||
|
@ -204,6 +204,19 @@ impl FileDescriptor {
|
|||||||
let stdio = unsafe { std::process::Stdio::from_raw_fd(fd) };
|
let stdio = unsafe { std::process::Stdio::from_raw_fd(fd) };
|
||||||
Ok(stdio)
|
Ok(stdio)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn set_non_blocking_impl(&mut self, non_blocking: bool) -> anyhow::Result<()> {
|
||||||
|
let on = if non_blocking { 1 } else { 0 };
|
||||||
|
let res = unsafe { libc::ioctl(self.handle.as_raw_file_descriptor(), libc::FIONBIO, &on) };
|
||||||
|
if res != 0 {
|
||||||
|
bail!(
|
||||||
|
"failed to change non-blocking mode: {:?}",
|
||||||
|
std::io::Error::last_os_error()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pipe {
|
impl Pipe {
|
||||||
|
@ -19,8 +19,9 @@ use winapi::um::processthreadsapi::*;
|
|||||||
use winapi::um::winbase::{FILE_TYPE_CHAR, FILE_TYPE_DISK, FILE_TYPE_PIPE};
|
use winapi::um::winbase::{FILE_TYPE_CHAR, FILE_TYPE_DISK, FILE_TYPE_PIPE};
|
||||||
use winapi::um::winnt::HANDLE;
|
use winapi::um::winnt::HANDLE;
|
||||||
use winapi::um::winsock2::{
|
use winapi::um::winsock2::{
|
||||||
accept, bind, closesocket, connect, getsockname, htonl, listen, WSAPoll, WSASocketW,
|
accept, bind, closesocket, connect, getsockname, htonl, ioctlsocket, listen, WSAPoll,
|
||||||
WSAStartup, INVALID_SOCKET, SOCKET, SOCK_STREAM, WSADATA, WSA_FLAG_NO_HANDLE_INHERIT,
|
WSASocketW, WSAStartup, INVALID_SOCKET, SOCKET, SOCK_STREAM, WSADATA,
|
||||||
|
WSA_FLAG_NO_HANDLE_INHERIT,
|
||||||
};
|
};
|
||||||
pub use winapi::um::winsock2::{POLLERR, POLLHUP, POLLIN, POLLOUT, WSAPOLLFD as pollfd};
|
pub use winapi::um::winsock2::{POLLERR, POLLHUP, POLLIN, POLLOUT, WSAPOLLFD as pollfd};
|
||||||
|
|
||||||
@ -88,14 +89,15 @@ impl<T: FromRawSocket> FromRawSocketDescriptor for T {
|
|||||||
unsafe impl Send for OwnedHandle {}
|
unsafe impl Send for OwnedHandle {}
|
||||||
|
|
||||||
impl OwnedHandle {
|
impl OwnedHandle {
|
||||||
fn probe_handle_type_if_unknown(handle: HANDLE, handle_type: HandleType) -> HandleType {
|
fn probe_handle_type_if_unknown(handle: RawHandle, handle_type: HandleType) -> HandleType {
|
||||||
match handle_type {
|
match handle_type {
|
||||||
HandleType::Unknown => Self::probe_handle_type(handle),
|
HandleType::Unknown => Self::probe_handle_type(handle),
|
||||||
t => t,
|
t => t,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn probe_handle_type(handle: HANDLE) -> HandleType {
|
pub(crate) fn probe_handle_type(handle: RawHandle) -> HandleType {
|
||||||
|
let handle = handle as HANDLE;
|
||||||
match unsafe { GetFileType(handle) } {
|
match unsafe { GetFileType(handle) } {
|
||||||
FILE_TYPE_CHAR => HandleType::Char,
|
FILE_TYPE_CHAR => HandleType::Char,
|
||||||
FILE_TYPE_DISK => HandleType::Disk,
|
FILE_TYPE_DISK => HandleType::Disk,
|
||||||
@ -212,6 +214,29 @@ impl FileDescriptor {
|
|||||||
let stdio = unsafe { std::process::Stdio::from_raw_handle(handle) };
|
let stdio = unsafe { std::process::Stdio::from_raw_handle(handle) };
|
||||||
Ok(stdio)
|
Ok(stdio)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn set_non_blocking_impl(&mut self, non_blocking: bool) -> anyhow::Result<()> {
|
||||||
|
if !self.handle.is_socket_handle() {
|
||||||
|
bail!("only socket descriptors can change their non-blocking mode on windows");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut on = if non_blocking { 1 } else { 0 };
|
||||||
|
let res = unsafe {
|
||||||
|
ioctlsocket(
|
||||||
|
self.as_raw_socket() as SOCKET,
|
||||||
|
winapi::um::winsock2::FIONBIO,
|
||||||
|
&mut on,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
if res != 0 {
|
||||||
|
bail!(
|
||||||
|
"failed to change non-blocking mode: {:?}",
|
||||||
|
std::io::Error::last_os_error()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoRawHandle for FileDescriptor {
|
impl IntoRawHandle for FileDescriptor {
|
||||||
|
Loading…
Reference in New Issue
Block a user