diff options
Diffstat (limited to 'msg_socket2/src/fd.rs')
-rw-r--r-- | msg_socket2/src/fd.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/msg_socket2/src/fd.rs b/msg_socket2/src/fd.rs new file mode 100644 index 0000000..648be3e --- /dev/null +++ b/msg_socket2/src/fd.rs @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// Copyright 2020, Alyssa Ross + +use libc::close; +use std::mem::forget; +use std::os::unix::prelude::*; + +/// A type representing ownership of a file descriptor. +pub struct Fd(RawFd); + +impl Fd { + /// Construct an owned `Fd` from a raw file descriptor. + /// + /// This function is unsafe because `Fd` must be the sole owner of + /// the file descriptor, so that it can be closed when the `Fd` is + /// dropped. + pub unsafe fn new(fd: RawFd) -> Self { + Self(fd) + } + + /// Converts this `Fd` into a different implementation of + /// `FromRawFd` containing the same file descriptor. + /// + /// No checks that the file descriptor is of the appropriate type + /// are performed. The file descriptor will remain open. + pub fn specialize<T: FromRawFd>(self) -> T { + let fd = self.into_raw_fd(); + + // Safe because we transfer ownership of the file descriptor. + unsafe { T::from_raw_fd(fd) } + } +} + +impl IntoRawFd for Fd { + fn into_raw_fd(self) -> RawFd { + let fd = self.0; + forget(self); + fd + } +} + +impl AsRawFd for Fd { + fn as_raw_fd(&self) -> RawFd { + self.0 + } +} + +impl FromRawFd for Fd { + unsafe fn from_raw_fd(fd: RawFd) -> Self { + Self(fd) + } +} + +impl Drop for Fd { + fn drop(&mut self) { + // Safe because we have sole ownership of fd. + unsafe { close(self.0) }; + } +} |