1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
//! The purpose of this crate is to make it a bit more ergonomic for portable //! applications that need to work with the platform level `RawFd` and //! `RawHandle` types. //! Rather than conditionally using `RawFd` and `RawHandle`, the `FileDescriptor` //! type can be used to manage ownership, duplicate, read and write. //! The `Pipe` type makes it more convenient to create a pipe and manage //! the lifetime of both the read and write ends of that pipe. use failure::Fallible; #[cfg(unix)] mod unix; #[cfg(unix)] pub use crate::unix::*; #[cfg(windows)] mod windows; #[cfg(windows)] pub use crate::windows::*; /// `AsRawFileDescriptor` is a platform independent trait for returning /// a non-owning reference to the underlying platform file descriptor /// type. pub trait AsRawFileDescriptor { fn as_raw_file_descriptor(&self) -> RawFileDescriptor; } /// `IntoRawFileDescriptor` is a platform independent trait for converting /// an instance into the underlying platform file descriptor type. pub trait IntoRawFileDescriptor { fn into_raw_file_descriptor(self) -> RawFileDescriptor; } /// `FromRawFileDescriptor` is a platform independent trait for creating /// an instance from the underlying platform file descriptor type. /// Because the platform file descriptor type has no inherent ownership /// management, the `from_raw_file_descrptor` function is marked as unsafe /// to indicate that care must be taken by the caller to ensure that it /// is used appropriately. pub trait FromRawFileDescriptor { unsafe fn from_raw_file_descrptor(fd: RawFileDescriptor) -> Self; } /// `OwnedHandle` allows managing the lifetime of the platform `RawFileDescriptor` /// type. It is exposed in the interface of this crate primarily for convenience /// on Windows where the system handle type is used for a variety of objects /// that don't support reading and writing. #[derive(Debug)] pub struct OwnedHandle { handle: RawFileDescriptor, } impl OwnedHandle { /// Create a new handle from some object that is convertible into /// the system `RawFileDescriptor` type. This consumes the parameter /// and replaces it with an `OwnedHandle` instance. pub fn new<F: IntoRawFileDescriptor>(f: F) -> Self { Self { handle: f.into_raw_file_descriptor(), } } /// Attempt to duplicate the underlying handle and return an /// `OwnedHandle` wrapped around the duplicate. Since the duplication /// requires kernel resources that may not be available, this is a /// potentially fallible operation. /// The returned handle has a separate lifetime from the source, but /// references the same object at the kernel level. pub fn try_clone(&self) -> Fallible<Self> { Self::dup(self) } /// Attempt to duplicate the underlying handle from an object that is /// representable as the systemm `RawFileDescriptor` type and return an /// `OwnedHandle` wrapped around the duplicate. Since the duplication /// requires kernel resources that may not be available, this is a /// potentially fallible operation. /// The returned handle has a separate lifetime from the source, but /// references the same object at the kernel level. pub fn dup<F: AsRawFileDescriptor>(f: &F) -> Fallible<Self> { Self::dup_impl(f) } } /// `FileDescriptor` is a thin wrapper on top of the `OwnedHandle` type that /// exposes the ability to Read and Write to the platform `RawFileDescriptor`. #[derive(Debug)] pub struct FileDescriptor { handle: OwnedHandle, } impl FileDescriptor { /// Create a new descriptor from some object that is convertible into /// the system `RawFileDescriptor` type. This consumes the parameter /// and replaces it with a `FileDescriptor` instance. pub fn new<F: IntoRawFileDescriptor>(f: F) -> Self { let handle = OwnedHandle::new(f); Self { handle } } /// Attempt to duplicate the underlying handle from an object that is /// representable as the systemm `RawFileDescriptor` type and return a /// `FileDescriptor` wrapped around the duplicate. Since the duplication /// requires kernel resources that may not be available, this is a /// potentially fallible operation. /// The returned handle has a separate lifetime from the source, but /// references the same object at the kernel level. pub fn dup<F: AsRawFileDescriptor>(f: &F) -> Fallible<Self> { OwnedHandle::dup(f).map(|handle| Self { handle }) } /// Attempt to duplicate the underlying handle and return a /// `FileDescriptor` wrapped around the duplicate. Since the duplication /// requires kernel resources that may not be available, this is a /// potentially fallible operation. /// The returned handle has a separate lifetime from the source, but /// references the same object at the kernel level. pub fn try_clone(&self) -> Fallible<Self> { self.handle.try_clone().map(|handle| Self { handle }) } /// A convenience method for creating a `std::process::Stdio` object /// to be used for eg: redirecting the stdio streams of a child /// process. The `Stdio` is created using a duplicated handle so /// that the source handle remains alive. pub fn as_stdio(&self) -> Fallible<std::process::Stdio> { self.as_stdio_impl() } } /// Represents the readable and writable ends of a pair of descriptors /// connected via a kernel pipe. pub struct Pipe { pub read: FileDescriptor, pub write: FileDescriptor, }