summary refs log tree commit diff
path: root/msg_socket2/src/fd.rs
diff options
context:
space:
mode:
Diffstat (limited to 'msg_socket2/src/fd.rs')
-rw-r--r--msg_socket2/src/fd.rs59
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) };
+    }
+}