Skip to content

Commit

Permalink
std: Stabilize parts of std::os::platform::io
Browse files Browse the repository at this point in the history
This commit stabilizes the platform-specific `io` modules, specifically around
the traits having to do with the raw representation of each object on each
platform.

Specifically, the following material was stabilized:

* `AsRaw{Fd,Socket,Handle}`
* `RawFd` (renamed from `Fd`)
* `RawHandle` (renamed from `Handle`)
* `RawSocket` (renamed from `Socket`)
* `AsRaw{Fd,Socket,Handle}` implementations
* `std::os::{unix, windows}::io`

The following material was added as `#[unstable]`:

* `FromRaw{Fd,Socket,Handle}`
* Implementations for various primitives

There are a number of future improvements that are possible to make to this
module, but this should cover a good bit of functionality desired from these
modules for now. Some specific future additions may include:

* `IntoRawXXX` traits to consume the raw representation and cancel the
  auto-destructor.
* `Fd`, `Socket`, and `Handle` abstractions that behave like Rust objects and
  have nice methods for various syscalls.

At this time though, these are considered backwards-compatible extensions and
will not be stabilized at this time.

This commit is a breaking change due to the addition of `Raw` in from of the
type aliases in each of the platform-specific modules.

[breaking-change]
  • Loading branch information
alexcrichton committed Mar 26, 2015
1 parent 557d434 commit 6370f29
Show file tree
Hide file tree
Showing 11 changed files with 263 additions and 59 deletions.
12 changes: 9 additions & 3 deletions src/libstd/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ mod tempdir;
#[stable(feature = "rust1", since = "1.0.0")]
pub struct File {
inner: fs_imp::File,
path: PathBuf,
path: Option<PathBuf>,
}

/// Metadata information about a file.
Expand Down Expand Up @@ -171,7 +171,7 @@ impl File {
reason = "this abstraction is imposed by this library instead \
of the underlying OS and may be removed")]
pub fn path(&self) -> Option<&Path> {
Some(&self.path)
self.path.as_ref().map(|p| &**p)
}

/// Attempt to sync all OS-internal metadata to disk.
Expand Down Expand Up @@ -273,6 +273,12 @@ impl File {
impl AsInner<fs_imp::File> for File {
fn as_inner(&self) -> &fs_imp::File { &self.inner }
}
impl FromInner<fs_imp::File> for File {
fn from_inner(f: fs_imp::File) -> File {
File { inner: f, path: None }
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
Expand Down Expand Up @@ -381,7 +387,7 @@ impl OpenOptions {
pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
let path = path.as_ref();
let inner = try!(fs_imp::File::open(path, &self.0));
Ok(File { path: path.to_path_buf(), inner: inner })
Ok(File { path: Some(path.to_path_buf()), inner: inner })
}
}

Expand Down
12 changes: 11 additions & 1 deletion src/libstd/net/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use io::prelude::*;
use io;
use net::{ToSocketAddrs, SocketAddr, Shutdown};
use sys_common::net2 as net_imp;
use sys_common::AsInner;
use sys_common::{AsInner, FromInner};

/// A structure which represents a TCP stream between a local socket and a
/// remote socket.
Expand Down Expand Up @@ -172,6 +172,10 @@ impl AsInner<net_imp::TcpStream> for TcpStream {
fn as_inner(&self) -> &net_imp::TcpStream { &self.0 }
}

impl FromInner<net_imp::TcpStream> for TcpStream {
fn from_inner(inner: net_imp::TcpStream) -> TcpStream { TcpStream(inner) }
}

impl TcpListener {
/// Creates a new `TcpListener` which will be bound to the specified
/// address.
Expand Down Expand Up @@ -245,6 +249,12 @@ impl AsInner<net_imp::TcpListener> for TcpListener {
fn as_inner(&self) -> &net_imp::TcpListener { &self.0 }
}

impl FromInner<net_imp::TcpListener> for TcpListener {
fn from_inner(inner: net_imp::TcpListener) -> TcpListener {
TcpListener(inner)
}
}

#[cfg(test)]
mod tests {
use prelude::v1::*;
Expand Down
6 changes: 5 additions & 1 deletion src/libstd/net/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use prelude::v1::*;
use io::{self, Error, ErrorKind};
use net::{ToSocketAddrs, SocketAddr, IpAddr};
use sys_common::net2 as net_imp;
use sys_common::AsInner;
use sys_common::{AsInner, FromInner};

/// A User Datagram Protocol socket.
///
Expand Down Expand Up @@ -140,6 +140,10 @@ impl AsInner<net_imp::UdpSocket> for UdpSocket {
fn as_inner(&self) -> &net_imp::UdpSocket { &self.0 }
}

impl FromInner<net_imp::UdpSocket> for UdpSocket {
fn from_inner(inner: net_imp::UdpSocket) -> UdpSocket { UdpSocket(inner) }
}

#[cfg(test)]
mod tests {
use prelude::v1::*;
Expand Down
18 changes: 18 additions & 0 deletions src/libstd/sys/common/net2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@ impl TcpStream {
}
}

impl FromInner<Socket> for TcpStream {
fn from_inner(socket: Socket) -> TcpStream {
TcpStream { inner: socket }
}
}

////////////////////////////////////////////////////////////////////////////////
// TCP listeners
////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -275,6 +281,12 @@ impl TcpListener {
}
}

impl FromInner<Socket> for TcpListener {
fn from_inner(socket: Socket) -> TcpListener {
TcpListener { inner: socket }
}
}

////////////////////////////////////////////////////////////////////////////////
// UDP
////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -387,3 +399,9 @@ impl UdpSocket {
self.inner.duplicate().map(|s| UdpSocket { inner: s })
}
}

impl FromInner<Socket> for UdpSocket {
fn from_inner(socket: Socket) -> UdpSocket {
UdpSocket { inner: socket }
}
}
115 changes: 92 additions & 23 deletions src/libstd/sys/unix/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,102 +32,171 @@
#![stable(feature = "rust1", since = "1.0.0")]

/// Unix-specific extensions to general I/O primitives
#[unstable(feature = "io_ext",
reason = "may want a slightly different organization or a more \
general file descriptor primitive")]
#[stable(feature = "rust1", since = "1.0.0")]
pub mod io {
#[allow(deprecated)] use old_io;
use fs;
use libc;
use net;
use sys_common::AsInner;
use sys_common::{net2, AsInner, FromInner};
use sys;

/// Raw file descriptors.
pub type Fd = libc::c_int;

/// Extract raw file descriptor
#[stable(feature = "rust1", since = "1.0.0")]
pub type RawFd = libc::c_int;

/// A trait to extract the raw unix file descriptor from an underlying
/// object.
///
/// This is only available on unix platforms and must be imported in order
/// to call the method. Windows platforms have a corresponding `AsRawHandle`
/// and `AsRawSocket` set of traits.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawFd {
/// Extract the raw file descriptor, without taking any ownership.
fn as_raw_fd(&self) -> Fd;
/// Extract the raw file descriptor.
///
/// This method does **not** pass ownership of the raw file descriptor
/// to the caller. The descriptor is only guarantee to be valid while
/// the original object has not yet been destroyed.
#[stable(feature = "rust1", since = "1.0.0")]
fn as_raw_fd(&self) -> RawFd;
}

/// A trait to express the ability to construct an object from a raw file
/// descriptor.
#[unstable(feature = "from_raw_os",
reason = "recent addition to std::os::unix::io")]
pub trait FromRawFd {
/// Constructs a new instances of `Self` from the given raw file
/// descriptor.
///
/// This function **consumes ownership** of the specified file
/// descriptor. The returned object will take responsibility for closing
/// it when the object goes out of scope.
///
/// Callers should normally only pass in a valid file descriptor to this
/// method or otherwise methods will return errors.
fn from_raw_fd(fd: RawFd) -> Self;
}

#[allow(deprecated)]
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for old_io::fs::File {
fn as_raw_fd(&self) -> Fd {
fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for fs::File {
fn as_raw_fd(&self) -> Fd {
fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd().raw()
}
}
#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
impl FromRawFd for fs::File {
fn from_raw_fd(fd: RawFd) -> fs::File {
fs::File::from_inner(sys::fs2::File::from_inner(fd))
}
}

#[allow(deprecated)]
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for old_io::pipe::PipeStream {
fn as_raw_fd(&self) -> Fd {
fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}

#[allow(deprecated)]
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for old_io::net::pipe::UnixStream {
fn as_raw_fd(&self) -> Fd {
fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}

#[allow(deprecated)]
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for old_io::net::pipe::UnixListener {
fn as_raw_fd(&self) -> Fd {
fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}

#[allow(deprecated)]
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for old_io::net::pipe::UnixAcceptor {
fn as_raw_fd(&self) -> Fd {
fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl AsRawFd for old_io::net::tcp::TcpStream {
fn as_raw_fd(&self) -> Fd {
fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl AsRawFd for old_io::net::tcp::TcpListener {
fn as_raw_fd(&self) -> Fd {
fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl AsRawFd for old_io::net::tcp::TcpAcceptor {
fn as_raw_fd(&self) -> Fd {
fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}

#[allow(deprecated)]
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for old_io::net::udp::UdpSocket {
fn as_raw_fd(&self) -> Fd {
fn as_raw_fd(&self) -> RawFd {
self.as_inner().fd()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::TcpStream {
fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::TcpListener {
fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for net::UdpSocket {
fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
}

#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
impl FromRawFd for net::TcpStream {
fn from_raw_fd(fd: RawFd) -> net::TcpStream {
let socket = sys::net::Socket::from_inner(fd);
net::TcpStream::from_inner(net2::TcpStream::from_inner(socket))
}
}
#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
impl FromRawFd for net::TcpListener {
fn from_raw_fd(fd: RawFd) -> net::TcpListener {
let socket = sys::net::Socket::from_inner(fd);
net::TcpListener::from_inner(net2::TcpListener::from_inner(socket))
}
}
#[unstable(feature = "from_raw_os", reason = "trait is unstable")]
impl FromRawFd for net::UdpSocket {
fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
let socket = sys::net::Socket::from_inner(fd);
net::UdpSocket::from_inner(net2::UdpSocket::from_inner(socket))
}
}
}

Expand Down Expand Up @@ -302,7 +371,7 @@ pub mod process {
#[stable(feature = "rust1", since = "1.0.0")]
pub mod prelude {
#[doc(no_inline)]
pub use super::io::{Fd, AsRawFd};
pub use super::io::{RawFd, AsRawFd};
#[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
pub use super::ffi::{OsStrExt, OsStringExt};
#[doc(no_inline)]
Expand Down
6 changes: 6 additions & 0 deletions src/libstd/sys/unix/fs2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,12 @@ fn cstr(path: &Path) -> io::Result<CString> {
Ok(cstring)
}

impl FromInner<c_int> for File {
fn from_inner(fd: c_int) -> File {
File(FileDesc::new(fd))
}
}

pub fn mkdir(p: &Path) -> io::Result<()> {
let p = try!(cstr(p));
try!(cvt(unsafe { libc::mkdir(p.as_ptr(), 0o777) }));
Expand Down
6 changes: 5 additions & 1 deletion src/libstd/sys/unix/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use str;
use sys::c;
use net::SocketAddr;
use sys::fd::FileDesc;
use sys_common::AsInner;
use sys_common::{AsInner, FromInner};

pub use sys::{cvt, cvt_r};

Expand Down Expand Up @@ -72,3 +72,7 @@ impl Socket {
impl AsInner<c_int> for Socket {
fn as_inner(&self) -> &c_int { self.0.as_inner() }
}

impl FromInner<c_int> for Socket {
fn from_inner(fd: c_int) -> Socket { Socket(FileDesc::new(fd)) }
}
Loading

0 comments on commit 6370f29

Please sign in to comment.