Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::{
use io_lifetimes::{AsFd, FromFd, OwnedFd};

#[cfg(windows)]
use io_lifetimes::{AsHandle, FromHandle, OwnedHandle};
use io_lifetimes::{AsHandle, FromHandle, InvalidHandleError, OwnedHandle};
#[cfg(windows)]
use std::{convert::TryInto, ptr::null_mut};

Expand Down Expand Up @@ -74,7 +74,7 @@ fn main() -> io::Result<()> {
null_mut(),
)
.try_into()
.map_err(|()| io::Error::last_os_error())?;
.map_err(|_err| io::Error::last_os_error())?;

// Borrow the handle to write to it.
let mut number_of_bytes_written = 0;
Expand Down
8 changes: 4 additions & 4 deletions src/example_ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#[cfg(any(unix, target_os = "wasi"))]
use crate::{BorrowedFd, OwnedFd};
#[cfg(windows)]
use crate::{BorrowedHandle, HandleOrInvalid, OwnedHandle};
use crate::{BorrowedHandle, HandleOrInvalid};

#[cfg(any(unix, target_os = "wasi"))]
use libc::{c_char, c_int, c_void, size_t, ssize_t};
Expand All @@ -30,9 +30,9 @@ extern "C" {
#[cfg(any(unix, target_os = "wasi"))]
pub use libc::{O_CLOEXEC, O_CREAT, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY};

/// The Windows analogs of the above. Note the use of [`HandleOrInvalid`] as
/// the return type for `CreateFileW`, since that function is defined to return
/// [`INVALID_HANDLE_VALUE`] on error instead of null.
// The Windows analogs of the above. Note the use of [`HandleOrInvalid`] as
// the return type for `CreateFileW`, since that function is defined to return
// [`INVALID_HANDLE_VALUE`] on error instead of null.
#[cfg(windows)]
extern "system" {
pub fn CreateFileW(
Expand Down
8 changes: 6 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ pub use traits::{FromHandle, FromSocket, IntoHandle, IntoSocket};
pub use types::{BorrowedFd, OwnedFd};
#[cfg(not(io_lifetimes_use_std))]
#[cfg(windows)]
pub use types::{BorrowedHandle, BorrowedSocket, HandleOrInvalid, OwnedHandle, OwnedSocket};
pub use types::{
BorrowedHandle, BorrowedSocket, HandleOrInvalid, InvalidHandleError, NullHandleError,
OwnedHandle, OwnedSocket,
};

#[cfg(io_lifetimes_use_std)]
#[cfg(unix)]
Expand All @@ -67,7 +70,8 @@ pub use std::os::wasi::io::{AsFd, BorrowedFd, OwnedFd};
#[cfg(io_lifetimes_use_std)]
#[cfg(windows)]
pub use std::os::windows::io::{
AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, HandleOrInvalid, OwnedHandle, OwnedSocket,
AsHandle, AsSocket, BorrowedHandle, BorrowedSocket, HandleOrInvalid, InvalidHandleError,
NullHandleError, OwnedHandle, OwnedSocket,
};

// io-lifetimes defined `FromFd`/`IntoFd` traits instead of just using
Expand Down
40 changes: 34 additions & 6 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,17 +491,17 @@ impl BorrowedSocket<'_> {

#[cfg(windows)]
impl TryFrom<HandleOrInvalid> for OwnedHandle {
type Error = ();
type Error = InvalidHandleError;

#[inline]
fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, ()> {
fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, InvalidHandleError> {
let raw = handle_or_invalid.0;
if raw == INVALID_HANDLE_VALUE {
// Don't call `CloseHandle`; it'd be harmless, except that it could
// overwrite the `GetLastError` error.
forget(handle_or_invalid);

Err(())
Err(InvalidHandleError(()))
} else {
Ok(OwnedHandle { handle: raw })
}
Expand All @@ -510,23 +510,51 @@ impl TryFrom<HandleOrInvalid> for OwnedHandle {

#[cfg(windows)]
impl TryFrom<HandleOrNull> for OwnedHandle {
type Error = ();
type Error = NullHandleError;

#[inline]
fn try_from(handle_or_null: HandleOrNull) -> Result<Self, ()> {
fn try_from(handle_or_null: HandleOrNull) -> Result<Self, NullHandleError> {
let raw = handle_or_null.0;
if raw.is_null() {
// Don't call `CloseHandle`; it'd be harmless, except that it could
// overwrite the `GetLastError` error.
forget(handle_or_null);

Err(())
Err(NullHandleError(()))
} else {
Ok(OwnedHandle { handle: raw })
}
}
}

/// This is the error type used by [`HandleOrNull`] when attempting to convert
/// into a handle, to indicate that the value is null.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NullHandleError(());

impl fmt::Display for NullHandleError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
"A HandleOrNull could not be converted to a handle because it was null".fmt(fmt)
}
}

impl std::error::Error for NullHandleError {}

/// This is the error type used by [`HandleOrInvalid`] when attempting to
/// convert into a handle, to indicate that the value is
/// `INVALID_HANDLE_VALUE`.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InvalidHandleError(());

impl fmt::Display for InvalidHandleError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
"A HandleOrInvalid could not be converted to a handle because it was INVALID_HANDLE_VALUE"
.fmt(fmt)
}
}

impl std::error::Error for InvalidHandleError {}

#[cfg(any(unix, target_os = "wasi"))]
impl AsRawFd for BorrowedFd<'_> {
#[inline]
Expand Down
6 changes: 3 additions & 3 deletions tests/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#[cfg(any(unix, windows))]
use io_lifetimes::example_ffi::*;
#[cfg(windows)]
use io_lifetimes::OwnedHandle;
use io_lifetimes::{InvalidHandleError, OwnedHandle};
#[cfg(windows)]
use std::{convert::TryInto, ptr::null_mut};
#[cfg(windows)]
Expand All @@ -29,7 +29,7 @@ fn test_file_not_found() {
#[cfg(windows)]
#[test]
fn test_file_not_found() {
let handle: Result<OwnedHandle, ()> = unsafe {
let handle: Result<OwnedHandle, InvalidHandleError> = unsafe {
CreateFileW(
[
'C' as u16, ':' as _, '/' as _, 'n' as _, 'o' as _, '/' as _, 's' as _, 'u' as _,
Expand Down Expand Up @@ -61,7 +61,7 @@ fn test_file_found() {
#[cfg(windows)]
#[test]
fn test_file_found() {
let handle: Result<OwnedHandle, ()> = unsafe {
let handle: Result<OwnedHandle, InvalidHandleError> = unsafe {
CreateFileW(
[
'C' as u16, 'a' as _, 'r' as _, 'g' as _, 'o' as _, '.' as _, 't' as _, 'o' as _,
Expand Down
4 changes: 2 additions & 2 deletions tests/niche-optimizations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ use std::mem::size_of;
#[cfg(any(unix, target_os = "wasi"))]
use io_lifetimes::{BorrowedFd, OwnedFd};
#[cfg(windows)]
use io_lifetimes::{BorrowedHandle, BorrowedSocket, OwnedHandle, OwnedSocket};
use io_lifetimes::{BorrowedSocket, OwnedSocket};

#[cfg(unix)]
use std::os::unix::io::RawFd;
#[cfg(target_os = "wasi")]
use std::os::wasi::io::RawFd;
#[cfg(windows)]
use std::os::windows::io::{RawHandle, RawSocket};
use std::os::windows::io::RawSocket;

#[cfg(all(rustc_attrs, any(unix, target_os = "wasi")))]
#[test]
Expand Down