|
| 1 | +//! Raw Unix-like file descriptors. |
| 2 | +
|
| 3 | +#![stable(feature = "rust1", since = "1.0.0")] |
| 4 | + |
| 5 | +use crate::fs; |
| 6 | +use crate::io; |
| 7 | +use crate::os::raw; |
| 8 | +#[cfg(unix)] |
| 9 | +use crate::os::unix::io::OwnedFd; |
| 10 | +#[cfg(target_os = "wasi")] |
| 11 | +use crate::os::wasi::io::OwnedFd; |
| 12 | +use crate::sys_common::{AsInner, IntoInner}; |
| 13 | + |
| 14 | +/// Raw file descriptors. |
| 15 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 16 | +pub type RawFd = raw::c_int; |
| 17 | + |
| 18 | +/// A trait to extract the raw file descriptor from an underlying object. |
| 19 | +/// |
| 20 | +/// This is only available on unix and WASI platforms and must be imported in |
| 21 | +/// order to call the method. Windows platforms have a corresponding |
| 22 | +/// `AsRawHandle` and `AsRawSocket` set of traits. |
| 23 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 24 | +pub trait AsRawFd { |
| 25 | + /// Extracts the raw file descriptor. |
| 26 | + /// |
| 27 | + /// This method does **not** pass ownership of the raw file descriptor |
| 28 | + /// to the caller. The descriptor is only guaranteed to be valid while |
| 29 | + /// the original object has not yet been destroyed. |
| 30 | + /// |
| 31 | + /// # Example |
| 32 | + /// |
| 33 | + /// ```no_run |
| 34 | + /// use std::fs::File; |
| 35 | + /// # use std::io; |
| 36 | + /// #[cfg(unix)] |
| 37 | + /// use std::os::unix::io::{AsRawFd, RawFd}; |
| 38 | + /// #[cfg(target_os = "wasi")] |
| 39 | + /// use std::os::wasi::io::{AsRawFd, RawFd}; |
| 40 | + /// |
| 41 | + /// let mut f = File::open("foo.txt")?; |
| 42 | + /// // Note that `raw_fd` is only valid as long as `f` exists. |
| 43 | + /// let raw_fd: RawFd = f.as_raw_fd(); |
| 44 | + /// # Ok::<(), io::Error>(()) |
| 45 | + /// ``` |
| 46 | + #[stable(feature = "rust1", since = "1.0.0")] |
| 47 | + fn as_raw_fd(&self) -> RawFd; |
| 48 | +} |
| 49 | + |
| 50 | +/// A trait to express the ability to construct an object from a raw file |
| 51 | +/// descriptor. |
| 52 | +#[stable(feature = "from_raw_os", since = "1.1.0")] |
| 53 | +pub trait FromRawFd { |
| 54 | + /// Constructs a new instance of `Self` from the given raw file |
| 55 | + /// descriptor. |
| 56 | + /// |
| 57 | + /// This function **consumes ownership** of the specified file |
| 58 | + /// descriptor. The returned object will take responsibility for closing |
| 59 | + /// it when the object goes out of scope. |
| 60 | + /// |
| 61 | + /// This function is also unsafe as the primitives currently returned |
| 62 | + /// have the contract that they are the sole owner of the file |
| 63 | + /// descriptor they are wrapping. Usage of this function could |
| 64 | + /// accidentally allow violating this contract which can cause memory |
| 65 | + /// unsafety in code that relies on it being true. |
| 66 | + /// |
| 67 | + /// # Example |
| 68 | + /// |
| 69 | + /// ```no_run |
| 70 | + /// use std::fs::File; |
| 71 | + /// # use std::io; |
| 72 | + /// #[cfg(unix)] |
| 73 | + /// use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd}; |
| 74 | + /// #[cfg(target_os = "wasi")] |
| 75 | + /// use std::os::wasi::io::{FromRawFd, IntoRawFd, RawFd}; |
| 76 | + /// |
| 77 | + /// let f = File::open("foo.txt")?; |
| 78 | + /// let raw_fd: RawFd = f.into_raw_fd(); |
| 79 | + /// // SAFETY: no other functions should call `from_raw_fd`, so there |
| 80 | + /// // is only one owner for the file descriptor. |
| 81 | + /// let f = unsafe { File::from_raw_fd(raw_fd) }; |
| 82 | + /// # Ok::<(), io::Error>(()) |
| 83 | + /// ``` |
| 84 | + #[stable(feature = "from_raw_os", since = "1.1.0")] |
| 85 | + unsafe fn from_raw_fd(fd: RawFd) -> Self; |
| 86 | +} |
| 87 | + |
| 88 | +/// A trait to express the ability to consume an object and acquire ownership of |
| 89 | +/// its raw file descriptor. |
| 90 | +#[stable(feature = "into_raw_os", since = "1.4.0")] |
| 91 | +pub trait IntoRawFd { |
| 92 | + /// Consumes this object, returning the raw underlying file descriptor. |
| 93 | + /// |
| 94 | + /// This function **transfers ownership** of the underlying file descriptor |
| 95 | + /// to the caller. Callers are then the unique owners of the file descriptor |
| 96 | + /// and must close the descriptor once it's no longer needed. |
| 97 | + /// |
| 98 | + /// # Example |
| 99 | + /// |
| 100 | + /// ```no_run |
| 101 | + /// use std::fs::File; |
| 102 | + /// # use std::io; |
| 103 | + /// #[cfg(unix)] |
| 104 | + /// use std::os::unix::io::{IntoRawFd, RawFd}; |
| 105 | + /// #[cfg(target_os = "wasi")] |
| 106 | + /// use std::os::wasi::io::{IntoRawFd, RawFd}; |
| 107 | + /// |
| 108 | + /// let f = File::open("foo.txt")?; |
| 109 | + /// let raw_fd: RawFd = f.into_raw_fd(); |
| 110 | + /// # Ok::<(), io::Error>(()) |
| 111 | + /// ``` |
| 112 | + #[stable(feature = "into_raw_os", since = "1.4.0")] |
| 113 | + fn into_raw_fd(self) -> RawFd; |
| 114 | +} |
| 115 | + |
| 116 | +#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")] |
| 117 | +impl AsRawFd for RawFd { |
| 118 | + #[inline] |
| 119 | + fn as_raw_fd(&self) -> RawFd { |
| 120 | + *self |
| 121 | + } |
| 122 | +} |
| 123 | +#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")] |
| 124 | +impl IntoRawFd for RawFd { |
| 125 | + #[inline] |
| 126 | + fn into_raw_fd(self) -> RawFd { |
| 127 | + self |
| 128 | + } |
| 129 | +} |
| 130 | +#[stable(feature = "raw_fd_reflexive_traits", since = "1.48.0")] |
| 131 | +impl FromRawFd for RawFd { |
| 132 | + #[inline] |
| 133 | + unsafe fn from_raw_fd(fd: RawFd) -> RawFd { |
| 134 | + fd |
| 135 | + } |
| 136 | +} |
| 137 | + |
| 138 | +#[stable(feature = "rust1", since = "1.0.0")] |
| 139 | +impl AsRawFd for fs::File { |
| 140 | + #[inline] |
| 141 | + fn as_raw_fd(&self) -> RawFd { |
| 142 | + self.as_inner().as_raw_fd() |
| 143 | + } |
| 144 | +} |
| 145 | +#[stable(feature = "from_raw_os", since = "1.1.0")] |
| 146 | +impl FromRawFd for fs::File { |
| 147 | + #[inline] |
| 148 | + unsafe fn from_raw_fd(fd: RawFd) -> fs::File { |
| 149 | + unsafe { fs::File::from(OwnedFd::from_raw_fd(fd)) } |
| 150 | + } |
| 151 | +} |
| 152 | +#[stable(feature = "into_raw_os", since = "1.4.0")] |
| 153 | +impl IntoRawFd for fs::File { |
| 154 | + #[inline] |
| 155 | + fn into_raw_fd(self) -> RawFd { |
| 156 | + self.into_inner().into_inner().into_raw_fd() |
| 157 | + } |
| 158 | +} |
| 159 | + |
| 160 | +#[stable(feature = "asraw_stdio", since = "1.21.0")] |
| 161 | +impl AsRawFd for io::Stdin { |
| 162 | + #[inline] |
| 163 | + fn as_raw_fd(&self) -> RawFd { |
| 164 | + libc::STDIN_FILENO |
| 165 | + } |
| 166 | +} |
| 167 | + |
| 168 | +#[stable(feature = "asraw_stdio", since = "1.21.0")] |
| 169 | +impl AsRawFd for io::Stdout { |
| 170 | + #[inline] |
| 171 | + fn as_raw_fd(&self) -> RawFd { |
| 172 | + libc::STDOUT_FILENO |
| 173 | + } |
| 174 | +} |
| 175 | + |
| 176 | +#[stable(feature = "asraw_stdio", since = "1.21.0")] |
| 177 | +impl AsRawFd for io::Stderr { |
| 178 | + #[inline] |
| 179 | + fn as_raw_fd(&self) -> RawFd { |
| 180 | + libc::STDERR_FILENO |
| 181 | + } |
| 182 | +} |
| 183 | + |
| 184 | +#[stable(feature = "asraw_stdio_locks", since = "1.35.0")] |
| 185 | +impl<'a> AsRawFd for io::StdinLock<'a> { |
| 186 | + #[inline] |
| 187 | + fn as_raw_fd(&self) -> RawFd { |
| 188 | + libc::STDIN_FILENO |
| 189 | + } |
| 190 | +} |
| 191 | + |
| 192 | +#[stable(feature = "asraw_stdio_locks", since = "1.35.0")] |
| 193 | +impl<'a> AsRawFd for io::StdoutLock<'a> { |
| 194 | + #[inline] |
| 195 | + fn as_raw_fd(&self) -> RawFd { |
| 196 | + libc::STDOUT_FILENO |
| 197 | + } |
| 198 | +} |
| 199 | + |
| 200 | +#[stable(feature = "asraw_stdio_locks", since = "1.35.0")] |
| 201 | +impl<'a> AsRawFd for io::StderrLock<'a> { |
| 202 | + #[inline] |
| 203 | + fn as_raw_fd(&self) -> RawFd { |
| 204 | + libc::STDERR_FILENO |
| 205 | + } |
| 206 | +} |
0 commit comments