Skip to content

Commit e555003

Browse files
committed
Factor out a common RawFd/AsRawFd/etc for Unix and WASI.
1 parent 0377a63 commit e555003

File tree

16 files changed

+355
-525
lines changed

16 files changed

+355
-525
lines changed

library/std/src/os/fd/mod.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! Owned and borrowed Unix-like file descriptors.
2+
3+
#![unstable(feature = "io_safety", issue = "87074")]
4+
#![deny(unsafe_op_in_unsafe_fn)]
5+
6+
// `RawFd`, `AsRawFd`, etc.
7+
pub mod raw;
8+
9+
// `OwnedFd`, `AsFd`, etc.
10+
pub mod owned;
11+
12+
// Implementations for `AsRawFd` etc. for network types.
13+
mod net;

library/std/src/os/wasi/net/raw_fd.rs renamed to library/std/src/os/fd/net.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use crate::os::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
2-
use crate::sys_common::{AsInner, FromInner, IntoInner};
1+
use crate::os::fd::owned::OwnedFd;
2+
use crate::os::fd::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
3+
use crate::sys_common::{self, AsInner, FromInner, IntoInner};
34
use crate::{net, sys};
45

56
macro_rules! impl_as_raw_fd {
@@ -23,7 +24,7 @@ macro_rules! impl_from_raw_fd {
2324
unsafe fn from_raw_fd(fd: RawFd) -> net::$t {
2425
unsafe {
2526
let socket = sys::net::Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd)));
26-
net::$t::from_inner(sys::net::$t::from_inner(socket))
27+
net::$t::from_inner(sys_common::net::$t::from_inner(socket))
2728
}
2829
}
2930
}

library/std/src/os/fd.rs renamed to library/std/src/os/fd/owned.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,11 @@
33
#![unstable(feature = "io_safety", issue = "87074")]
44
#![deny(unsafe_op_in_unsafe_fn)]
55

6-
#[cfg(unix)]
7-
use super::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
8-
#[cfg(target_os = "wasi")]
9-
use super::wasi::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
6+
use super::raw::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
107
use crate::fmt;
118
use crate::fs;
129
use crate::marker::PhantomData;
1310
use crate::mem::forget;
14-
use crate::os::raw;
1511
use crate::sys_common::{AsInner, FromInner, IntoInner};
1612

1713
/// A borrowed file descriptor.
@@ -123,7 +119,7 @@ impl Drop for OwnedFd {
123119
// the file descriptor was closed or not, and if we retried (for
124120
// something like EINTR), we might close another valid file descriptor
125121
// opened after we closed ours.
126-
let _ = libc::close(self.fd as raw::c_int);
122+
let _ = libc::close(self.fd);
127123
}
128124
}
129125
}

library/std/src/os/fd/raw.rs

+206
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
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+
}

library/std/src/os/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,5 +122,5 @@ mod imp {
122122
#[stable(feature = "os", since = "1.0.0")]
123123
pub use imp::*;
124124

125-
#[cfg(any(unix, target_os = "wasi"))]
125+
#[cfg(any(unix, target_os = "wasi", doc))]
126126
mod fd;

library/std/src/os/unix/io/fd.rs

+1-51
Original file line numberDiff line numberDiff line change
@@ -6,54 +6,4 @@
66
#[cfg(test)]
77
mod tests;
88

9-
use crate::sys_common::{AsInner, IntoInner};
10-
11-
pub use super::super::super::super::fd::*;
12-
13-
#[unstable(feature = "io_safety", issue = "87074")]
14-
impl AsFd for crate::process::ChildStdin {
15-
#[inline]
16-
fn as_fd(&self) -> BorrowedFd<'_> {
17-
self.as_inner().as_fd()
18-
}
19-
}
20-
21-
#[unstable(feature = "io_safety", issue = "87074")]
22-
impl From<crate::process::ChildStdin> for OwnedFd {
23-
#[inline]
24-
fn from(child_stdin: crate::process::ChildStdin) -> OwnedFd {
25-
child_stdin.into_inner().into_inner().into_inner()
26-
}
27-
}
28-
29-
#[unstable(feature = "io_safety", issue = "87074")]
30-
impl AsFd for crate::process::ChildStdout {
31-
#[inline]
32-
fn as_fd(&self) -> BorrowedFd<'_> {
33-
self.as_inner().as_fd()
34-
}
35-
}
36-
37-
#[unstable(feature = "io_safety", issue = "87074")]
38-
impl From<crate::process::ChildStdout> for OwnedFd {
39-
#[inline]
40-
fn from(child_stdout: crate::process::ChildStdout) -> OwnedFd {
41-
child_stdout.into_inner().into_inner().into_inner()
42-
}
43-
}
44-
45-
#[unstable(feature = "io_safety", issue = "87074")]
46-
impl AsFd for crate::process::ChildStderr {
47-
#[inline]
48-
fn as_fd(&self) -> BorrowedFd<'_> {
49-
self.as_inner().as_fd()
50-
}
51-
}
52-
53-
#[unstable(feature = "io_safety", issue = "87074")]
54-
impl From<crate::process::ChildStderr> for OwnedFd {
55-
#[inline]
56-
fn from(child_stderr: crate::process::ChildStderr) -> OwnedFd {
57-
child_stderr.into_inner().into_inner().into_inner()
58-
}
59-
}
9+
pub use crate::os::fd::owned::*;

0 commit comments

Comments
 (0)