// 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(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) }; } }