mirror of
https://github.com/wez/wezterm.git
synced 2024-08-17 10:10:23 +03:00
prep for filedescriptor release
This commit is contained in:
parent
56a0de9362
commit
240bc8033c
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "filedescriptor"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
authors = ["Wez Furlong"]
|
||||
edition = "2018"
|
||||
repository = "https://github.com/wez/wzsh"
|
||||
@ -8,6 +8,7 @@ description = "More ergonomic wrappers around RawFd and RawHandle"
|
||||
license = "MIT"
|
||||
documentation = "https://docs.rs/filedescriptor"
|
||||
readme = "README.md"
|
||||
keywords = ["socketpair", "pipe", "poll", "filedescriptor"]
|
||||
|
||||
[dependencies]
|
||||
failure = "0.1"
|
||||
|
@ -1,3 +1,5 @@
|
||||
<!-- cargo-sync-readme start -->
|
||||
|
||||
The purpose of this crate is to make it a bit more ergonomic for portable
|
||||
applications that need to work with the platform level `RawFd` and
|
||||
`RawHandle` types.
|
||||
@ -11,7 +13,7 @@ This is a bit of a contrived example, but demonstrates how to avoid
|
||||
the conditional code that would otherwise be required to deal with
|
||||
calling `as_raw_fd` and `as_raw_handle`:
|
||||
|
||||
```rust
|
||||
```
|
||||
use filedescriptor::{FileDescriptor, FromRawFileDescriptor};
|
||||
use failure::Fallible;
|
||||
use std::io::Write;
|
||||
@ -32,9 +34,9 @@ fn print_something() -> Fallible<()> {
|
||||
The `Pipe` type makes it more convenient to create a pipe and manage
|
||||
the lifetime of both the read and write ends of that pipe.
|
||||
|
||||
```rust
|
||||
```
|
||||
use filedescriptor::Pipe;
|
||||
use std::io::{Read,Write};
|
||||
use std::io::{Read, Write};
|
||||
use failure::Error;
|
||||
|
||||
let mut pipe = Pipe::new()?;
|
||||
@ -44,6 +46,54 @@ drop(pipe.write);
|
||||
let mut s = String::new();
|
||||
pipe.read.read_to_string(&mut s)?;
|
||||
assert_eq!(s, "hello");
|
||||
# Ok::<(), Error>(())
|
||||
```
|
||||
|
||||
## Socketpair
|
||||
The `socketpair` function returns a pair of connected `SOCK_STREAM`
|
||||
sockets and functions both on posix and windows systems.
|
||||
|
||||
```
|
||||
use std::io::{Read, Write};
|
||||
use failure::Error;
|
||||
|
||||
let (mut a, mut b) = filedescriptor::socketpair()?;
|
||||
a.write(b"hello")?;
|
||||
drop(a);
|
||||
|
||||
let mut s = String::new();
|
||||
b.read_to_string(&mut s)?;
|
||||
assert_eq!(s, "hello");
|
||||
```
|
||||
|
||||
## Polling
|
||||
The `mio` crate offers powerful and scalable IO multiplexing, but there
|
||||
are some situations where `mio` doesn't fit. The `filedescriptor` crate
|
||||
offers a `poll(2)` compatible interface suitable for testing the readiness
|
||||
of a set of file descriptors. On unix systems this is a very thin wrapper
|
||||
around `poll(2)`, except on macOS where it is actually a wrapper around
|
||||
the `select(2)` interface. On Windows systems the winsock `WSAPoll`
|
||||
function is used instead.
|
||||
|
||||
```
|
||||
use filedescriptor::*;
|
||||
use failure::Error;
|
||||
use std::time::Duration;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
let (mut a, mut b) = filedescriptor::socketpair()?;
|
||||
let mut poll_array = [pollfd {
|
||||
fd: a.as_socket_descriptor(),
|
||||
events: POLLIN,
|
||||
revents: 0
|
||||
}];
|
||||
// sleeps for 20 milliseconds because `a` is not yet ready
|
||||
assert_eq!(poll(&mut poll_array, Some(Duration::from_millis(20)))?, 0);
|
||||
|
||||
b.write(b"hello")?;
|
||||
|
||||
// Now a is ready for read
|
||||
assert_eq!(poll(&mut poll_array, Some(Duration::from_millis(20)))?, 1);
|
||||
|
||||
```
|
||||
|
||||
<!-- cargo-sync-readme end -->
|
||||
|
@ -34,7 +34,7 @@
|
||||
//!
|
||||
//! ```
|
||||
//! use filedescriptor::Pipe;
|
||||
//! use std::io::{Read,Write};
|
||||
//! use std::io::{Read, Write};
|
||||
//! use failure::Error;
|
||||
//!
|
||||
//! let mut pipe = Pipe::new()?;
|
||||
@ -46,6 +46,56 @@
|
||||
//! assert_eq!(s, "hello");
|
||||
//! # Ok::<(), Error>(())
|
||||
//! ```
|
||||
//!
|
||||
//! ## Socketpair
|
||||
//! The `socketpair` function returns a pair of connected `SOCK_STREAM`
|
||||
//! sockets and functions both on posix and windows systems.
|
||||
//!
|
||||
//! ```
|
||||
//! use std::io::{Read, Write};
|
||||
//! use failure::Error;
|
||||
//!
|
||||
//! let (mut a, mut b) = filedescriptor::socketpair()?;
|
||||
//! a.write(b"hello")?;
|
||||
//! drop(a);
|
||||
//!
|
||||
//! let mut s = String::new();
|
||||
//! b.read_to_string(&mut s)?;
|
||||
//! assert_eq!(s, "hello");
|
||||
//! # Ok::<(), Error>(())
|
||||
//! ```
|
||||
//!
|
||||
//! ## Polling
|
||||
//! The `mio` crate offers powerful and scalable IO multiplexing, but there
|
||||
//! are some situations where `mio` doesn't fit. The `filedescriptor` crate
|
||||
//! offers a `poll(2)` compatible interface suitable for testing the readiness
|
||||
//! of a set of file descriptors. On unix systems this is a very thin wrapper
|
||||
//! around `poll(2)`, except on macOS where it is actually a wrapper around
|
||||
//! the `select(2)` interface. On Windows systems the winsock `WSAPoll`
|
||||
//! function is used instead.
|
||||
//!
|
||||
//! ```
|
||||
//! use filedescriptor::*;
|
||||
//! use failure::Error;
|
||||
//! use std::time::Duration;
|
||||
//! use std::io::{Read, Write};
|
||||
//!
|
||||
//! let (mut a, mut b) = filedescriptor::socketpair()?;
|
||||
//! let mut poll_array = [pollfd {
|
||||
//! fd: a.as_socket_descriptor(),
|
||||
//! events: POLLIN,
|
||||
//! revents: 0
|
||||
//! }];
|
||||
//! // sleeps for 20 milliseconds because `a` is not yet ready
|
||||
//! assert_eq!(poll(&mut poll_array, Some(Duration::from_millis(20)))?, 0);
|
||||
//!
|
||||
//! b.write(b"hello")?;
|
||||
//!
|
||||
//! // Now a is ready for read
|
||||
//! assert_eq!(poll(&mut poll_array, Some(Duration::from_millis(20)))?, 1);
|
||||
//!
|
||||
//! # Ok::<(), Error>(())
|
||||
//! ```
|
||||
use failure::Fallible;
|
||||
#[cfg(unix)]
|
||||
mod unix;
|
||||
@ -62,6 +112,9 @@ pub use crate::windows::*;
|
||||
/// type.
|
||||
pub trait AsRawFileDescriptor {
|
||||
fn as_raw_file_descriptor(&self) -> RawFileDescriptor;
|
||||
fn as_socket_descriptor(&self) -> SocketDescriptor {
|
||||
self.as_raw_file_descriptor() as SocketDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
/// `IntoRawFileDescriptor` is a platform independent trait for converting
|
||||
@ -229,6 +282,9 @@ use std::time::Duration;
|
||||
/// error will returned. This limitation could potentially be lifted in the
|
||||
/// future.
|
||||
///
|
||||
/// On Windows, `WSAPoll` is used to implement readiness checking, which has
|
||||
/// the consequence that it can only be used with sockets.
|
||||
///
|
||||
/// If `duration` is `None`, then `poll` will block until any of the requested
|
||||
/// events are ready. Otherwise, `duration` specifies how long to wait for
|
||||
/// readiness before giving up.
|
||||
|
@ -10,6 +10,11 @@ use std::os::unix::prelude::*;
|
||||
/// for avoiding using `cfg` blocks in platform independent code.
|
||||
pub type RawFileDescriptor = RawFd;
|
||||
|
||||
/// `SocketDescriptor` is a platform independent type alias for the
|
||||
/// underlying platform socket descriptor type. It is primarily useful
|
||||
/// for avoiding using `cfg` blocks in platform independent code.
|
||||
pub type SocketDescriptor = RawFd;
|
||||
|
||||
impl<T: AsRawFd> AsRawFileDescriptor for T {
|
||||
fn as_raw_file_descriptor(&self) -> RawFileDescriptor {
|
||||
self.as_raw_fd()
|
||||
|
@ -20,7 +20,7 @@ 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, SOCK_STREAM, WSADATA, WSA_FLAG_NO_HANDLE_INHERIT,
|
||||
WSAStartup, INVALID_SOCKET, SOCKET, SOCK_STREAM, WSADATA, WSA_FLAG_NO_HANDLE_INHERIT,
|
||||
};
|
||||
pub use winapi::um::winsock2::{POLLERR, POLLHUP, POLLIN, POLLOUT, WSAPOLLFD as pollfd};
|
||||
|
||||
@ -29,6 +29,11 @@ pub use winapi::um::winsock2::{POLLERR, POLLHUP, POLLIN, POLLOUT, WSAPOLLFD as p
|
||||
/// for avoiding using `cfg` blocks in platform independent code.
|
||||
pub type RawFileDescriptor = RawHandle;
|
||||
|
||||
/// `SocketDescriptor` is a platform independent type alias for the
|
||||
/// underlying platform socket descriptor type. It is primarily useful
|
||||
/// for avoiding using `cfg` blocks in platform independent code.
|
||||
pub type SocketDescriptor = SOCKET;
|
||||
|
||||
impl<T: AsRawHandle> AsRawFileDescriptor for T {
|
||||
fn as_raw_file_descriptor(&self) -> RawFileDescriptor {
|
||||
self.as_raw_handle()
|
||||
|
Loading…
Reference in New Issue
Block a user