]>
Commit | Line | Data |
---|---|---|
dfeec247 | 1 | #![unstable(reason = "not public", issue = "none", feature = "fd")] |
54a0048b | 2 | |
1b1a35ee XL |
3 | #[cfg(test)] |
4 | mod tests; | |
5 | ||
532ac7d7 | 6 | use crate::cmp; |
f2b60f7d | 7 | use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read}; |
94222f64 | 8 | use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; |
532ac7d7 | 9 | use crate::sys::cvt; |
94222f64 | 10 | use crate::sys_common::{AsInner, FromInner, IntoInner}; |
532ac7d7 | 11 | |
04454e1e FG |
12 | #[cfg(any( |
13 | target_os = "android", | |
14 | target_os = "linux", | |
15 | target_os = "emscripten", | |
16 | target_os = "l4re" | |
17 | ))] | |
18 | use libc::off64_t; | |
19 | #[cfg(not(any( | |
20 | target_os = "linux", | |
21 | target_os = "emscripten", | |
22 | target_os = "l4re", | |
23 | target_os = "android" | |
24 | )))] | |
25 | use libc::off_t as off64_t; | |
26 | ||
32a655c1 | 27 | #[derive(Debug)] |
94222f64 | 28 | pub struct FileDesc(OwnedFd); |
85aaf69f | 29 | |
3dfed10e XL |
30 | // The maximum read limit on most POSIX-like systems is `SSIZE_MAX`, |
31 | // with the man page quoting that if the count of bytes to read is | |
32 | // greater than `SSIZE_MAX` the result is "unspecified". | |
33 | // | |
34 | // On macOS, however, apparently the 64-bit libc is either buggy or | |
35 | // intentionally showing odd behavior by rejecting any read with a size | |
36 | // larger than or equal to INT_MAX. To handle both of these the read | |
37 | // size is capped on both platforms. | |
38 | #[cfg(target_os = "macos")] | |
923072b8 | 39 | const READ_LIMIT: usize = libc::c_int::MAX as usize - 1; |
3dfed10e XL |
40 | #[cfg(not(target_os = "macos"))] |
41 | const READ_LIMIT: usize = libc::ssize_t::MAX as usize; | |
42 | ||
1b1a35ee XL |
43 | #[cfg(any( |
44 | target_os = "dragonfly", | |
45 | target_os = "freebsd", | |
46 | target_os = "ios", | |
47 | target_os = "macos", | |
48 | target_os = "netbsd", | |
49 | target_os = "openbsd", | |
064997fb | 50 | target_os = "watchos", |
1b1a35ee XL |
51 | ))] |
52 | const fn max_iov() -> usize { | |
53 | libc::IOV_MAX as usize | |
54 | } | |
3dfed10e | 55 | |
9ffffee4 FG |
56 | #[cfg(any( |
57 | target_os = "android", | |
58 | target_os = "emscripten", | |
59 | target_os = "linux", | |
60 | target_os = "nto", | |
61 | ))] | |
1b1a35ee XL |
62 | const fn max_iov() -> usize { |
63 | libc::UIO_MAXIOV as usize | |
3dfed10e XL |
64 | } |
65 | ||
1b1a35ee XL |
66 | #[cfg(not(any( |
67 | target_os = "android", | |
68 | target_os = "dragonfly", | |
69 | target_os = "emscripten", | |
70 | target_os = "freebsd", | |
71 | target_os = "ios", | |
72 | target_os = "linux", | |
73 | target_os = "macos", | |
74 | target_os = "netbsd", | |
9ffffee4 | 75 | target_os = "nto", |
1b1a35ee | 76 | target_os = "openbsd", |
064997fb FG |
77 | target_os = "horizon", |
78 | target_os = "watchos", | |
1b1a35ee XL |
79 | )))] |
80 | const fn max_iov() -> usize { | |
3dfed10e | 81 | 16 // The minimum value required by POSIX. |
32a655c1 SL |
82 | } |
83 | ||
85aaf69f | 84 | impl FileDesc { |
85aaf69f | 85 | pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { |
54a0048b | 86 | let ret = cvt(unsafe { |
94222f64 XL |
87 | libc::read( |
88 | self.as_raw_fd(), | |
923072b8 | 89 | buf.as_mut_ptr() as *mut libc::c_void, |
94222f64 XL |
90 | cmp::min(buf.len(), READ_LIMIT), |
91 | ) | |
54a0048b | 92 | })?; |
85aaf69f SL |
93 | Ok(ret as usize) |
94 | } | |
95 | ||
923072b8 | 96 | #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] |
48663c56 | 97 | pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { |
9fa01778 | 98 | let ret = cvt(unsafe { |
60c5eb7d | 99 | libc::readv( |
94222f64 | 100 | self.as_raw_fd(), |
9ffffee4 | 101 | bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec, |
923072b8 | 102 | cmp::min(bufs.len(), max_iov()) as libc::c_int, |
60c5eb7d | 103 | ) |
9fa01778 XL |
104 | })?; |
105 | Ok(ret as usize) | |
106 | } | |
107 | ||
923072b8 | 108 | #[cfg(any(target_os = "espidf", target_os = "horizon"))] |
94222f64 | 109 | pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { |
9ffffee4 | 110 | io::default_read_vectored(|b| self.read(b), bufs) |
94222f64 XL |
111 | } |
112 | ||
f9f354fc XL |
113 | #[inline] |
114 | pub fn is_read_vectored(&self) -> bool { | |
923072b8 | 115 | cfg!(not(any(target_os = "espidf", target_os = "horizon"))) |
f9f354fc XL |
116 | } |
117 | ||
54a0048b SL |
118 | pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> { |
119 | let mut me = self; | |
120 | (&mut me).read_to_end(buf) | |
121 | } | |
122 | ||
c30ab7b3 | 123 | pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> { |
a2a8927a XL |
124 | #[cfg(not(any(target_os = "linux", target_os = "android")))] |
125 | use libc::pread as pread64; | |
126 | #[cfg(any(target_os = "linux", target_os = "android"))] | |
127 | use libc::pread64; | |
c30ab7b3 SL |
128 | |
129 | unsafe { | |
a2a8927a | 130 | cvt(pread64( |
94222f64 | 131 | self.as_raw_fd(), |
923072b8 | 132 | buf.as_mut_ptr() as *mut libc::c_void, |
3dfed10e | 133 | cmp::min(buf.len(), READ_LIMIT), |
04454e1e | 134 | offset as off64_t, |
a2a8927a | 135 | )) |
60c5eb7d | 136 | .map(|n| n as usize) |
c30ab7b3 SL |
137 | } |
138 | } | |
139 | ||
f2b60f7d | 140 | pub fn read_buf(&self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> { |
a2a8927a XL |
141 | let ret = cvt(unsafe { |
142 | libc::read( | |
143 | self.as_raw_fd(), | |
f2b60f7d FG |
144 | cursor.as_mut().as_mut_ptr() as *mut libc::c_void, |
145 | cmp::min(cursor.capacity(), READ_LIMIT), | |
a2a8927a XL |
146 | ) |
147 | })?; | |
148 | ||
149 | // Safety: `ret` bytes were written to the initialized portion of the buffer | |
150 | unsafe { | |
f2b60f7d | 151 | cursor.advance(ret as usize); |
a2a8927a | 152 | } |
a2a8927a XL |
153 | Ok(()) |
154 | } | |
155 | ||
9ffffee4 FG |
156 | #[cfg(any( |
157 | target_os = "emscripten", | |
158 | target_os = "freebsd", | |
159 | target_os = "fuchsia", | |
160 | target_os = "illumos", | |
161 | target_os = "linux", | |
162 | target_os = "netbsd", | |
163 | ))] | |
164 | pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> { | |
165 | let ret = cvt(unsafe { | |
166 | libc::preadv( | |
167 | self.as_raw_fd(), | |
168 | bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec, | |
169 | cmp::min(bufs.len(), max_iov()) as libc::c_int, | |
170 | offset as _, | |
171 | ) | |
172 | })?; | |
173 | Ok(ret as usize) | |
174 | } | |
175 | ||
176 | #[cfg(not(any( | |
177 | target_os = "android", | |
178 | target_os = "emscripten", | |
179 | target_os = "freebsd", | |
180 | target_os = "fuchsia", | |
181 | target_os = "illumos", | |
182 | target_os = "ios", | |
183 | target_os = "linux", | |
184 | target_os = "macos", | |
185 | target_os = "netbsd", | |
186 | )))] | |
187 | pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> { | |
188 | io::default_read_vectored(|b| self.read_at(b, offset), bufs) | |
189 | } | |
190 | ||
191 | // We support some old Android versions that do not have `preadv` in libc, | |
192 | // so we use weak linkage and fallback to a direct syscall if not available. | |
193 | // | |
194 | // On 32-bit targets, we don't want to deal with weird ABI issues around | |
195 | // passing 64-bits parameters to syscalls, so we fallback to the default | |
196 | // implementation if `preadv` is not available. | |
197 | #[cfg(all(target_os = "android", target_pointer_width = "64"))] | |
198 | pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> { | |
199 | super::weak::syscall! { | |
200 | fn preadv( | |
201 | fd: libc::c_int, | |
202 | iovec: *const libc::iovec, | |
203 | n_iovec: libc::c_int, | |
204 | offset: off64_t | |
205 | ) -> isize | |
206 | } | |
207 | ||
208 | let ret = cvt(unsafe { | |
209 | preadv( | |
210 | self.as_raw_fd(), | |
211 | bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec, | |
212 | cmp::min(bufs.len(), max_iov()) as libc::c_int, | |
213 | offset as _, | |
214 | ) | |
215 | })?; | |
216 | Ok(ret as usize) | |
217 | } | |
218 | ||
219 | // We support old MacOS and iOS versions that do not have `preadv`. There is | |
220 | // no `syscall` possible in these platform. | |
221 | #[cfg(any( | |
222 | all(target_os = "android", target_pointer_width = "32"), | |
223 | target_os = "ios", | |
224 | target_os = "macos", | |
225 | ))] | |
226 | pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> { | |
227 | super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize); | |
228 | ||
229 | match preadv64.get() { | |
230 | Some(preadv) => { | |
231 | let ret = cvt(unsafe { | |
232 | preadv( | |
233 | self.as_raw_fd(), | |
234 | bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec, | |
235 | cmp::min(bufs.len(), max_iov()) as libc::c_int, | |
236 | offset as _, | |
237 | ) | |
238 | })?; | |
239 | Ok(ret as usize) | |
240 | } | |
241 | None => io::default_read_vectored(|b| self.read_at(b, offset), bufs), | |
242 | } | |
243 | } | |
244 | ||
85aaf69f | 245 | pub fn write(&self, buf: &[u8]) -> io::Result<usize> { |
54a0048b | 246 | let ret = cvt(unsafe { |
94222f64 XL |
247 | libc::write( |
248 | self.as_raw_fd(), | |
923072b8 | 249 | buf.as_ptr() as *const libc::c_void, |
94222f64 XL |
250 | cmp::min(buf.len(), READ_LIMIT), |
251 | ) | |
54a0048b | 252 | })?; |
85aaf69f SL |
253 | Ok(ret as usize) |
254 | } | |
9346a6ac | 255 | |
923072b8 | 256 | #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] |
48663c56 | 257 | pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { |
9fa01778 | 258 | let ret = cvt(unsafe { |
60c5eb7d | 259 | libc::writev( |
94222f64 | 260 | self.as_raw_fd(), |
60c5eb7d | 261 | bufs.as_ptr() as *const libc::iovec, |
923072b8 | 262 | cmp::min(bufs.len(), max_iov()) as libc::c_int, |
60c5eb7d | 263 | ) |
9fa01778 XL |
264 | })?; |
265 | Ok(ret as usize) | |
266 | } | |
267 | ||
923072b8 | 268 | #[cfg(any(target_os = "espidf", target_os = "horizon"))] |
94222f64 | 269 | pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { |
9ffffee4 | 270 | io::default_write_vectored(|b| self.write(b), bufs) |
94222f64 XL |
271 | } |
272 | ||
f9f354fc XL |
273 | #[inline] |
274 | pub fn is_write_vectored(&self) -> bool { | |
923072b8 | 275 | cfg!(not(any(target_os = "espidf", target_os = "horizon"))) |
f9f354fc XL |
276 | } |
277 | ||
c30ab7b3 | 278 | pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> { |
a2a8927a XL |
279 | #[cfg(not(any(target_os = "linux", target_os = "android")))] |
280 | use libc::pwrite as pwrite64; | |
281 | #[cfg(any(target_os = "linux", target_os = "android"))] | |
282 | use libc::pwrite64; | |
c30ab7b3 SL |
283 | |
284 | unsafe { | |
a2a8927a | 285 | cvt(pwrite64( |
94222f64 | 286 | self.as_raw_fd(), |
923072b8 | 287 | buf.as_ptr() as *const libc::c_void, |
3dfed10e | 288 | cmp::min(buf.len(), READ_LIMIT), |
04454e1e | 289 | offset as off64_t, |
a2a8927a | 290 | )) |
60c5eb7d | 291 | .map(|n| n as usize) |
c30ab7b3 SL |
292 | } |
293 | } | |
294 | ||
9ffffee4 FG |
295 | #[cfg(any( |
296 | target_os = "emscripten", | |
297 | target_os = "freebsd", | |
298 | target_os = "fuchsia", | |
299 | target_os = "illumos", | |
300 | target_os = "linux", | |
301 | target_os = "netbsd", | |
302 | ))] | |
303 | pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> { | |
304 | let ret = cvt(unsafe { | |
305 | libc::pwritev( | |
306 | self.as_raw_fd(), | |
307 | bufs.as_ptr() as *const libc::iovec, | |
308 | cmp::min(bufs.len(), max_iov()) as libc::c_int, | |
309 | offset as _, | |
310 | ) | |
311 | })?; | |
312 | Ok(ret as usize) | |
313 | } | |
314 | ||
315 | #[cfg(not(any( | |
316 | target_os = "android", | |
317 | target_os = "emscripten", | |
318 | target_os = "freebsd", | |
319 | target_os = "fuchsia", | |
320 | target_os = "illumos", | |
321 | target_os = "ios", | |
322 | target_os = "linux", | |
323 | target_os = "macos", | |
324 | target_os = "netbsd", | |
325 | )))] | |
326 | pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> { | |
327 | io::default_write_vectored(|b| self.write_at(b, offset), bufs) | |
328 | } | |
329 | ||
330 | // We support some old Android versions that do not have `pwritev` in libc, | |
331 | // so we use weak linkage and fallback to a direct syscall if not available. | |
332 | // | |
333 | // On 32-bit targets, we don't want to deal with weird ABI issues around | |
334 | // passing 64-bits parameters to syscalls, so we fallback to the default | |
335 | // implementation if `pwritev` is not available. | |
336 | #[cfg(all(target_os = "android", target_pointer_width = "64"))] | |
337 | pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> { | |
338 | super::weak::syscall! { | |
339 | fn pwritev( | |
340 | fd: libc::c_int, | |
341 | iovec: *const libc::iovec, | |
342 | n_iovec: libc::c_int, | |
343 | offset: off64_t | |
344 | ) -> isize | |
345 | } | |
346 | ||
347 | let ret = cvt(unsafe { | |
348 | pwritev( | |
349 | self.as_raw_fd(), | |
350 | bufs.as_ptr() as *const libc::iovec, | |
351 | cmp::min(bufs.len(), max_iov()) as libc::c_int, | |
352 | offset as _, | |
353 | ) | |
354 | })?; | |
355 | Ok(ret as usize) | |
356 | } | |
357 | ||
358 | // We support old MacOS and iOS versions that do not have `pwritev`. There is | |
359 | // no `syscall` possible in these platform. | |
360 | #[cfg(any( | |
361 | all(target_os = "android", target_pointer_width = "32"), | |
362 | target_os = "ios", | |
363 | target_os = "macos", | |
364 | ))] | |
365 | pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> { | |
366 | super::weak::weak!(fn pwritev64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize); | |
367 | ||
368 | match pwritev64.get() { | |
369 | Some(pwritev) => { | |
370 | let ret = cvt(unsafe { | |
371 | pwritev( | |
372 | self.as_raw_fd(), | |
373 | bufs.as_ptr() as *const libc::iovec, | |
374 | cmp::min(bufs.len(), max_iov()) as libc::c_int, | |
375 | offset as _, | |
376 | ) | |
377 | })?; | |
378 | Ok(ret as usize) | |
379 | } | |
380 | None => io::default_write_vectored(|b| self.write_at(b, offset), bufs), | |
381 | } | |
94b46f34 XL |
382 | } |
383 | ||
60c5eb7d XL |
384 | #[cfg(not(any( |
385 | target_env = "newlib", | |
386 | target_os = "solaris", | |
ba9703b0 | 387 | target_os = "illumos", |
60c5eb7d XL |
388 | target_os = "emscripten", |
389 | target_os = "fuchsia", | |
390 | target_os = "l4re", | |
391 | target_os = "linux", | |
392 | target_os = "haiku", | |
29967ef6 | 393 | target_os = "redox", |
9ffffee4 FG |
394 | target_os = "vxworks", |
395 | target_os = "nto", | |
60c5eb7d | 396 | )))] |
3157f602 | 397 | pub fn set_cloexec(&self) -> io::Result<()> { |
9346a6ac | 398 | unsafe { |
94222f64 | 399 | cvt(libc::ioctl(self.as_raw_fd(), libc::FIOCLEX))?; |
3157f602 | 400 | Ok(()) |
92a42be0 SL |
401 | } |
402 | } | |
60c5eb7d | 403 | #[cfg(any( |
923072b8 | 404 | all(target_env = "newlib", not(any(target_os = "espidf", target_os = "horizon"))), |
60c5eb7d | 405 | target_os = "solaris", |
ba9703b0 | 406 | target_os = "illumos", |
60c5eb7d XL |
407 | target_os = "emscripten", |
408 | target_os = "fuchsia", | |
409 | target_os = "l4re", | |
410 | target_os = "linux", | |
411 | target_os = "haiku", | |
29967ef6 | 412 | target_os = "redox", |
9ffffee4 FG |
413 | target_os = "vxworks", |
414 | target_os = "nto", | |
60c5eb7d | 415 | ))] |
3157f602 | 416 | pub fn set_cloexec(&self) -> io::Result<()> { |
92a42be0 | 417 | unsafe { |
94222f64 | 418 | let previous = cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFD))?; |
8bb4bdeb XL |
419 | let new = previous | libc::FD_CLOEXEC; |
420 | if new != previous { | |
94222f64 | 421 | cvt(libc::fcntl(self.as_raw_fd(), libc::F_SETFD, new))?; |
8bb4bdeb | 422 | } |
3157f602 | 423 | Ok(()) |
9346a6ac AL |
424 | } |
425 | } | |
923072b8 | 426 | #[cfg(any(target_os = "espidf", target_os = "horizon"))] |
94222f64 | 427 | pub fn set_cloexec(&self) -> io::Result<()> { |
923072b8 FG |
428 | // FD_CLOEXEC is not supported in ESP-IDF and Horizon OS but there's no need to, |
429 | // because neither supports spawning processes. | |
94222f64 XL |
430 | Ok(()) |
431 | } | |
7453a54e | 432 | |
8bb4bdeb XL |
433 | #[cfg(target_os = "linux")] |
434 | pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { | |
435 | unsafe { | |
923072b8 | 436 | let v = nonblocking as libc::c_int; |
94222f64 | 437 | cvt(libc::ioctl(self.as_raw_fd(), libc::FIONBIO, &v))?; |
8bb4bdeb XL |
438 | Ok(()) |
439 | } | |
440 | } | |
441 | ||
442 | #[cfg(not(target_os = "linux"))] | |
3157f602 | 443 | pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { |
54a0048b | 444 | unsafe { |
94222f64 | 445 | let previous = cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFL))?; |
54a0048b SL |
446 | let new = if nonblocking { |
447 | previous | libc::O_NONBLOCK | |
448 | } else { | |
449 | previous & !libc::O_NONBLOCK | |
450 | }; | |
8bb4bdeb | 451 | if new != previous { |
94222f64 | 452 | cvt(libc::fcntl(self.as_raw_fd(), libc::F_SETFL, new))?; |
8bb4bdeb | 453 | } |
3157f602 | 454 | Ok(()) |
54a0048b SL |
455 | } |
456 | } | |
457 | ||
5099ac24 | 458 | #[inline] |
7453a54e | 459 | pub fn duplicate(&self) -> io::Result<FileDesc> { |
5099ac24 | 460 | Ok(Self(self.0.try_clone()?)) |
7453a54e | 461 | } |
85aaf69f SL |
462 | } |
463 | ||
54a0048b SL |
464 | impl<'a> Read for &'a FileDesc { |
465 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | |
466 | (**self).read(buf) | |
467 | } | |
9ffffee4 FG |
468 | |
469 | fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> { | |
470 | (**self).read_buf(cursor) | |
471 | } | |
54a0048b SL |
472 | } |
473 | ||
94222f64 XL |
474 | impl AsInner<OwnedFd> for FileDesc { |
475 | fn as_inner(&self) -> &OwnedFd { | |
476 | &self.0 | |
477 | } | |
478 | } | |
479 | ||
480 | impl IntoInner<OwnedFd> for FileDesc { | |
481 | fn into_inner(self) -> OwnedFd { | |
482 | self.0 | |
483 | } | |
484 | } | |
485 | ||
486 | impl FromInner<OwnedFd> for FileDesc { | |
487 | fn from_inner(owned_fd: OwnedFd) -> Self { | |
488 | Self(owned_fd) | |
489 | } | |
490 | } | |
491 | ||
492 | impl AsFd for FileDesc { | |
493 | fn as_fd(&self) -> BorrowedFd<'_> { | |
494 | self.0.as_fd() | |
495 | } | |
496 | } | |
497 | ||
498 | impl AsRawFd for FileDesc { | |
499 | fn as_raw_fd(&self) -> RawFd { | |
500 | self.0.as_raw_fd() | |
501 | } | |
502 | } | |
503 | ||
504 | impl IntoRawFd for FileDesc { | |
505 | fn into_raw_fd(self) -> RawFd { | |
506 | self.0.into_raw_fd() | |
60c5eb7d | 507 | } |
85aaf69f SL |
508 | } |
509 | ||
94222f64 XL |
510 | impl FromRawFd for FileDesc { |
511 | unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { | |
512 | Self(FromRawFd::from_raw_fd(raw_fd)) | |
85aaf69f SL |
513 | } |
514 | } |