1
1
mirror of https://github.com/wez/wezterm.git synced 2024-08-17 02:00:25 +03:00

add FileDescriptor::set_non_blocking

This commit is contained in:
Wez Furlong 2020-01-15 08:24:41 -08:00
parent 55b4a08131
commit 08b0017c16
4 changed files with 53 additions and 5 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "filedescriptor"
version = "0.6.0"
version = "0.7.0"
authors = ["Wez Furlong"]
edition = "2018"
repository = "https://github.com/wez/wzsh"

View File

@ -247,6 +247,16 @@ impl FileDescriptor {
pub fn as_stdio(&self) -> anyhow::Result<std::process::Stdio> {
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

View File

@ -204,6 +204,19 @@ impl FileDescriptor {
let stdio = unsafe { std::process::Stdio::from_raw_fd(fd) };
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 {

View File

@ -19,8 +19,9 @@ use winapi::um::processthreadsapi::*;
use winapi::um::winbase::{FILE_TYPE_CHAR, FILE_TYPE_DISK, FILE_TYPE_PIPE};
use winapi::um::winnt::HANDLE;
use winapi::um::winsock2::{
accept, bind, closesocket, connect, getsockname, htonl, listen, WSAPoll, WSASocketW,
WSAStartup, INVALID_SOCKET, SOCKET, SOCK_STREAM, WSADATA, WSA_FLAG_NO_HANDLE_INHERIT,
accept, bind, closesocket, connect, getsockname, htonl, ioctlsocket, listen, WSAPoll,
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};
@ -88,14 +89,15 @@ impl<T: FromRawSocket> FromRawSocketDescriptor for T {
unsafe impl Send for 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 {
HandleType::Unknown => Self::probe_handle_type(handle),
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) } {
FILE_TYPE_CHAR => HandleType::Char,
FILE_TYPE_DISK => HandleType::Disk,
@ -212,6 +214,29 @@ impl FileDescriptor {
let stdio = unsafe { std::process::Stdio::from_raw_handle(handle) };
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 {