about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-03-26 16:18:29 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-03-26 16:40:36 -0700
commit6370f2978e485fd46bcb64f51a1c003395acfedc (patch)
tree32a1d0ad913d1180e71916b70044122fc7503bf3
parent557d4346a26266d2eb13f6b0adf106b8873b0da1 (diff)
downloadrust-6370f2978e485fd46bcb64f51a1c003395acfedc.tar.gz
rust-6370f2978e485fd46bcb64f51a1c003395acfedc.zip
std: Stabilize parts of std::os::platform::io
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]
-rw-r--r--src/libstd/fs/mod.rs12
-rw-r--r--src/libstd/net/tcp.rs12
-rw-r--r--src/libstd/net/udp.rs6
-rw-r--r--src/libstd/sys/common/net2.rs18
-rw-r--r--src/libstd/sys/unix/ext.rs115
-rw-r--r--src/libstd/sys/unix/fs2.rs6
-rw-r--r--src/libstd/sys/unix/net.rs6
-rw-r--r--src/libstd/sys/windows/ext.rs120
-rw-r--r--src/libstd/sys/windows/fs2.rs15
-rw-r--r--src/libstd/sys/windows/net.rs8
-rw-r--r--src/libstd/sys/windows/os.rs4
11 files changed, 263 insertions, 59 deletions
diff --git a/src/libstd/fs/mod.rs b/src/libstd/fs/mod.rs
index c1253706832..b01cb53388f 100644
--- a/src/libstd/fs/mod.rs
+++ b/src/libstd/fs/mod.rs
@@ -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.
@@ -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.
@@ -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> {
@@ -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 })
     }
 }
 
diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index 869faa795f9..9ed08d05e8b 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -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.
@@ -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.
@@ -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::*;
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index 81151114962..4aeb3d7c7c8 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -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.
 ///
@@ -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::*;
diff --git a/src/libstd/sys/common/net2.rs b/src/libstd/sys/common/net2.rs
index e213a86644f..8b54b7e6fb4 100644
--- a/src/libstd/sys/common/net2.rs
+++ b/src/libstd/sys/common/net2.rs
@@ -222,6 +222,12 @@ impl TcpStream {
     }
 }
 
+impl FromInner<Socket> for TcpStream {
+    fn from_inner(socket: Socket) -> TcpStream {
+        TcpStream { inner: socket }
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // TCP listeners
 ////////////////////////////////////////////////////////////////////////////////
@@ -275,6 +281,12 @@ impl TcpListener {
     }
 }
 
+impl FromInner<Socket> for TcpListener {
+    fn from_inner(socket: Socket) -> TcpListener {
+        TcpListener { inner: socket }
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // UDP
 ////////////////////////////////////////////////////////////////////////////////
@@ -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 }
+    }
+}
diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs
index 0805949d560..080cf5620fc 100644
--- a/src/libstd/sys/unix/ext.rs
+++ b/src/libstd/sys/unix/ext.rs
@@ -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))
+        }
     }
 }
 
@@ -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)]
diff --git a/src/libstd/sys/unix/fs2.rs b/src/libstd/sys/unix/fs2.rs
index 202e5ddaec4..80fc1235a31 100644
--- a/src/libstd/sys/unix/fs2.rs
+++ b/src/libstd/sys/unix/fs2.rs
@@ -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) }));
diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs
index b22fa33e562..00b907ce10c 100644
--- a/src/libstd/sys/unix/net.rs
+++ b/src/libstd/sys/unix/net.rs
@@ -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};
 
@@ -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)) }
+}
diff --git a/src/libstd/sys/windows/ext.rs b/src/libstd/sys/windows/ext.rs
index 7955397892b..2dd61861bd6 100644
--- a/src/libstd/sys/windows/ext.rs
+++ b/src/libstd/sys/windows/ext.rs
@@ -16,112 +16,188 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-#[unstable(feature = "io_ext",
-           reason = "organization may change slightly and the primitives \
-                     provided may be tweaked")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub mod io {
     use fs;
     use libc;
     use net;
-    use sys_common::AsInner;
+    use sys_common::{net2, AsInner, FromInner};
+    use sys;
 
     #[allow(deprecated)]
     use old_io;
 
     /// Raw HANDLEs.
-    pub type Handle = libc::HANDLE;
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub type RawHandle = libc::HANDLE;
 
     /// Raw SOCKETs.
-    pub type Socket = libc::SOCKET;
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub type RawSocket = libc::SOCKET;
 
     /// Extract raw handles.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub trait AsRawHandle {
         /// Extract the raw handle, without taking any ownership.
-        fn as_raw_handle(&self) -> Handle;
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn as_raw_handle(&self) -> RawHandle;
+    }
+
+    /// Construct I/O objects from raw handles.
+    #[unstable(feature = "from_raw_os",
+               reason = "recent addition to the std::os::windows::io module")]
+    pub trait FromRawHandle {
+        /// Construct a new I/O object from the specified raw handle.
+        ///
+        /// This function will **consume ownership** of the handle given,
+        /// passing responsibility for closing the handle to the returned
+        /// object.
+        fn from_raw_handle(handle: RawHandle) -> Self;
     }
 
     #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawHandle for old_io::fs::File {
-        fn as_raw_handle(&self) -> Handle {
+        fn as_raw_handle(&self) -> RawHandle {
             self.as_inner().handle()
         }
     }
 
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawHandle for fs::File {
-        fn as_raw_handle(&self) -> Handle {
+        fn as_raw_handle(&self) -> RawHandle {
             self.as_inner().handle().raw()
         }
     }
 
+    #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+    impl FromRawHandle for fs::File {
+        fn from_raw_handle(handle: RawHandle) -> fs::File {
+            fs::File::from_inner(sys::fs2::File::from_inner(handle))
+        }
+    }
+
     #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawHandle for old_io::pipe::PipeStream {
-        fn as_raw_handle(&self) -> Handle {
+        fn as_raw_handle(&self) -> RawHandle {
             self.as_inner().handle()
         }
     }
 
     #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawHandle for old_io::net::pipe::UnixStream {
-        fn as_raw_handle(&self) -> Handle {
+        fn as_raw_handle(&self) -> RawHandle {
             self.as_inner().handle()
         }
     }
 
     #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawHandle for old_io::net::pipe::UnixListener {
-        fn as_raw_handle(&self) -> Handle {
+        fn as_raw_handle(&self) -> RawHandle {
             self.as_inner().handle()
         }
     }
 
     #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawHandle for old_io::net::pipe::UnixAcceptor {
-        fn as_raw_handle(&self) -> Handle {
+        fn as_raw_handle(&self) -> RawHandle {
             self.as_inner().handle()
         }
     }
 
     /// Extract raw sockets.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub trait AsRawSocket {
-        fn as_raw_socket(&self) -> Socket;
+        /// Extract the underlying raw socket from this object.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn as_raw_socket(&self) -> RawSocket;
+    }
+
+    /// Create I/O objects from raw sockets.
+    #[unstable(feature = "from_raw_os", reason = "recent addition to module")]
+    pub trait FromRawSocket {
+        /// Creates a new I/O object from the given raw socket.
+        ///
+        /// This function will **consume ownership** of the socket provided and
+        /// it will be closed when the returned object goes out of scope.
+        fn from_raw_socket(sock: RawSocket) -> Self;
     }
 
     #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawSocket for old_io::net::tcp::TcpStream {
-        fn as_raw_socket(&self) -> Socket {
+        fn as_raw_socket(&self) -> RawSocket {
             self.as_inner().fd()
         }
     }
 
     #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawSocket for old_io::net::tcp::TcpListener {
-        fn as_raw_socket(&self) -> Socket {
+        fn as_raw_socket(&self) -> RawSocket {
             self.as_inner().socket()
         }
     }
 
     #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawSocket for old_io::net::tcp::TcpAcceptor {
-        fn as_raw_socket(&self) -> Socket {
+        fn as_raw_socket(&self) -> RawSocket {
             self.as_inner().socket()
         }
     }
 
     #[allow(deprecated)]
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawSocket for old_io::net::udp::UdpSocket {
-        fn as_raw_socket(&self) -> Socket {
+        fn as_raw_socket(&self) -> RawSocket {
             self.as_inner().fd()
         }
     }
 
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawSocket for net::TcpStream {
-        fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
+        fn as_raw_socket(&self) -> RawSocket {
+            *self.as_inner().socket().as_inner()
+        }
     }
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawSocket for net::TcpListener {
-        fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
+        fn as_raw_socket(&self) -> RawSocket {
+            *self.as_inner().socket().as_inner()
+        }
     }
+    #[stable(feature = "rust1", since = "1.0.0")]
     impl AsRawSocket for net::UdpSocket {
-        fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
+        fn as_raw_socket(&self) -> RawSocket {
+            *self.as_inner().socket().as_inner()
+        }
+    }
+
+    #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+    impl FromRawSocket for net::TcpStream {
+        fn from_raw_socket(sock: RawSocket) -> net::TcpStream {
+            let sock = sys::net::Socket::from_inner(sock);
+            net::TcpStream::from_inner(net2::TcpStream::from_inner(sock))
+        }
+    }
+    #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+    impl FromRawSocket for net::TcpListener {
+        fn from_raw_socket(sock: RawSocket) -> net::TcpListener {
+            let sock = sys::net::Socket::from_inner(sock);
+            net::TcpListener::from_inner(net2::TcpListener::from_inner(sock))
+        }
+    }
+    #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
+    impl FromRawSocket for net::UdpSocket {
+        fn from_raw_socket(sock: RawSocket) -> net::UdpSocket {
+            let sock = sys::net::Socket::from_inner(sock);
+            net::UdpSocket::from_inner(net2::UdpSocket::from_inner(sock))
+        }
     }
 }
 
@@ -230,7 +306,7 @@ pub mod fs {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub mod prelude {
     #[doc(no_inline)]
-    pub use super::io::{Socket, Handle, AsRawSocket, AsRawHandle};
+    pub use super::io::{RawSocket, RawHandle, AsRawSocket, AsRawHandle};
     #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::ffi::{OsStrExt, OsStringExt};
     #[doc(no_inline)]
diff --git a/src/libstd/sys/windows/fs2.rs b/src/libstd/sys/windows/fs2.rs
index 99835265111..d03e45649ed 100644
--- a/src/libstd/sys/windows/fs2.rs
+++ b/src/libstd/sys/windows/fs2.rs
@@ -20,11 +20,12 @@ use mem;
 use path::{Path, PathBuf};
 use ptr;
 use sync::Arc;
-use sys::handle::Handle as RawHandle;
+use sys::handle::Handle;
 use sys::{c, cvt};
+use sys_common::FromInner;
 use vec::Vec;
 
-pub struct File { handle: RawHandle }
+pub struct File { handle: Handle }
 pub struct FileAttr { data: c::WIN32_FILE_ATTRIBUTE_DATA }
 
 pub struct ReadDir {
@@ -192,7 +193,7 @@ impl File {
         if handle == libc::INVALID_HANDLE_VALUE {
             Err(Error::last_os_error())
         } else {
-            Ok(File { handle: RawHandle::new(handle) })
+            Ok(File { handle: Handle::new(handle) })
         }
     }
 
@@ -260,7 +261,13 @@ impl File {
         Ok(newpos as u64)
     }
 
-    pub fn handle(&self) -> &RawHandle { &self.handle }
+    pub fn handle(&self) -> &Handle { &self.handle }
+}
+
+impl FromInner<libc::HANDLE> for File {
+    fn from_inner(handle: libc::HANDLE) -> File {
+        File { handle: Handle::new(handle) }
+    }
 }
 
 pub fn to_utf16(s: &Path) -> Vec<u16> {
diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs
index 734268c70ac..b07b3d8651e 100644
--- a/src/libstd/sys/windows/net.rs
+++ b/src/libstd/sys/windows/net.rs
@@ -19,7 +19,7 @@ use num::{SignedInt, Int};
 use rt;
 use sync::{Once, ONCE_INIT};
 use sys::c;
-use sys_common::AsInner;
+use sys_common::{AsInner, FromInner};
 
 pub type wrlen_t = i32;
 
@@ -123,10 +123,14 @@ impl Socket {
 
 impl Drop for Socket {
     fn drop(&mut self) {
-        unsafe { cvt(libc::closesocket(self.0)).unwrap(); }
+        let _ = unsafe { libc::closesocket(self.0) };
     }
 }
 
 impl AsInner<libc::SOCKET> for Socket {
     fn as_inner(&self) -> &libc::SOCKET { &self.0 }
 }
+
+impl FromInner<libc::SOCKET> for Socket {
+    fn from_inner(sock: libc::SOCKET) -> Socket { Socket(sock) }
+}
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index 167db1e8ac2..5cd90b0902b 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -31,7 +31,7 @@ use ptr;
 use slice;
 use sys::c;
 use sys::fs::FileDesc;
-use sys::handle::Handle as RawHandle;
+use sys::handle::Handle;
 
 use libc::funcs::extra::kernel32::{
     GetEnvironmentStringsW,
@@ -369,7 +369,7 @@ pub fn home_dir() -> Option<PathBuf> {
         if c::OpenProcessToken(me, c::TOKEN_READ, &mut token) == 0 {
             return None
         }
-        let _handle = RawHandle::new(token);
+        let _handle = Handle::new(token);
         super::fill_utf16_buf_new(|buf, mut sz| {
             match c::GetUserProfileDirectoryW(token, buf, &mut sz) {
                 0 if libc::GetLastError() != 0 => 0,