]> git.lizzy.rs Git - rust.git/commitdiff
std: Make FromRawFd::from_raw_fd an unsafe method
authorAlex Crichton <alex@alexcrichton.com>
Thu, 9 Apr 2015 22:43:27 +0000 (15:43 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 9 Apr 2015 23:12:33 +0000 (16:12 -0700)
As pointed out in [RFC issue 1043][rfc] it is quite useful to have the standard
I/O types to provide the contract that they are the sole owner of the underlying
object they represent. This guarantee enables writing safe interfaces like the
`MemoryMap` API sketched out in that issue.

[rfc]: https://github.com/rust-lang/rfcs/issues/1043

As constructing objects from these raw handles may end up violating these
ownership gurantees, the functions for construction are now marked unsafe.

[breaking-change]
Closes rust-lang/rfcs#1043

src/libstd/sys/unix/ext.rs
src/libstd/sys/windows/ext.rs

index fbfbb40701fd9f5887a841ba7e50dde90ed36479..fa0f14b480789131ca3a1f67d95e513fee0b5f2c 100644 (file)
@@ -74,9 +74,12 @@ pub trait FromRawFd {
         /// 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;
+        /// This function is also unsafe as the primitives currently returned
+        /// have the contract that they are the sole owner of the file
+        /// descriptor they are wrapping. Usage of this function could
+        /// accidentally allow violating this contract which can cause memory
+        /// unsafety in code that relies on it being true.
+        unsafe fn from_raw_fd(fd: RawFd) -> Self;
     }
 
     #[allow(deprecated)]
@@ -95,7 +98,7 @@ fn as_raw_fd(&self) -> RawFd {
     }
     #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
     impl FromRawFd for fs::File {
-        fn from_raw_fd(fd: RawFd) -> fs::File {
+        unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
             fs::File::from_inner(sys::fs2::File::from_inner(fd))
         }
     }
@@ -179,21 +182,21 @@ 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 {
+        unsafe 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 {
+        unsafe 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 {
+        unsafe 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))
         }
index 2dd61861bd6dc8c78299ffb2b7c9065f3aef29c9..5f6e74d4b7251461a2e75f059f16c441cf85e04f 100644 (file)
@@ -52,7 +52,13 @@ pub trait FromRawHandle {
         /// 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;
+        ///
+        /// This function is also unsafe as the primitives currently returned
+        /// have the contract that they are the sole owner of the file
+        /// descriptor they are wrapping. Usage of this function could
+        /// accidentally allow violating this contract which can cause memory
+        /// unsafety in code that relies on it being true.
+        unsafe fn from_raw_handle(handle: RawHandle) -> Self;
     }
 
     #[allow(deprecated)]
@@ -72,7 +78,7 @@ fn as_raw_handle(&self) -> RawHandle {
 
     #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
     impl FromRawHandle for fs::File {
-        fn from_raw_handle(handle: RawHandle) -> fs::File {
+        unsafe fn from_raw_handle(handle: RawHandle) -> fs::File {
             fs::File::from_inner(sys::fs2::File::from_inner(handle))
         }
     }
@@ -124,7 +130,13 @@ pub trait FromRawSocket {
         ///
         /// 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;
+        ///
+        /// This function is also unsafe as the primitives currently returned
+        /// have the contract that they are the sole owner of the file
+        /// descriptor they are wrapping. Usage of this function could
+        /// accidentally allow violating this contract which can cause memory
+        /// unsafety in code that relies on it being true.
+        unsafe fn from_raw_socket(sock: RawSocket) -> Self;
     }
 
     #[allow(deprecated)]
@@ -180,21 +192,21 @@ fn as_raw_socket(&self) -> RawSocket {
 
     #[unstable(feature = "from_raw_os", reason = "trait is unstable")]
     impl FromRawSocket for net::TcpStream {
-        fn from_raw_socket(sock: RawSocket) -> net::TcpStream {
+        unsafe 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 {
+        unsafe 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 {
+        unsafe 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))
         }