Skip to content
Closed
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
target
Cargo.lock
.vscode/
61 changes: 61 additions & 0 deletions src/io/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,64 @@ impl<'context, T: AsFd + Into<OwnedFd> + From<OwnedFd>> Context for Owning<'cont
unsafe { T::from(OwnedFd::from_raw_fd(raw_fd).into()) }
}
}

/// A type implementing [`Context`] where the `Data` type is `RawFd`
///
/// # Safety
///
/// This is intended to be used for non-safe I/O types. Care must be taken to
/// ensure that the device is not closed while it is still in use by the kernel.
pub struct Raw {
_private: (),
}

impl Raw {
/// Create a new `Raw` context.
///
/// # Safety
///
/// See the safety requirements of [`Raw`].
#[inline]
pub unsafe fn new() -> Self {
Self { _private: () }
}
}

impl Context for Raw {
type Data = RawFd;
type Target = ValidFd;

fn acquire<'call>(&self, data: Self::Data) -> Ref<'call, Self::Target> {
// Safety: `data` is a raw file descriptor that is assumed to be valid.
Ref::new(ValidFd(data))
}

fn encode(&self, target: Ref<'_, Self::Target>) -> u64 {
target.0 as u64
}

unsafe fn decode<'call>(&self, raw: u64) -> Ref<'call, Self::Target> {
// Safety: `raw` is a raw file descriptor that is assumed to be valid.
Ref::new(ValidFd(raw as RawFd))
}

fn release(&self, target: Ref<'_, Self::Target>) -> Self::Data {
target.consume().0
}
}

/// Implements `AsFd` for `RawFd`.
///
/// # Safety
///
/// This is only instantiated by the `Raw` context, which is unsafe.
#[doc(hidden)]
pub struct ValidFd(RawFd);

impl AsFd for ValidFd {
#[inline]
fn as_fd(&self) -> BorrowedFd<'_> {
// SAFETY: The user has assured as that this file descriptor is valid.
unsafe { BorrowedFd::borrow_raw(self.0) }
}
}