提交 ca42a1be 编写于 作者: D Dan Gohman

Update the documentation for `{As,Into,From}Raw{Fd,Handle,Socket}`.

This change weakens the descriptions of the
`{as,into,from}_raw_{fd,handle,socket}` descriptions from saying that
they *do* express ownership relations to say that they are *typically used*
in ways that express ownership relations. This needed needed since, for
example, std's own [`RawFd`] implements `{As,From,Into}Fd` without any of
the ownership relationships.

This adds proper `# Safety` comments to `from_raw_{fd,handle,socket}`,
adds the requirement that raw handles be not opened with the
`FILE_FLAG_OVERLAPPED` flag, and merges the `OwnedHandle::from_raw_handle`
comment into the main `FromRawHandle::from_raw_handle` comment.

And, this changes `HandleOrNull` and `HandleOrInvalid` to not implement
`FromRawHandle`, since they are intended for limited use in FFI situations,
and not for generic use, and they have constraints that are stronger than
the those of `FromRawHandle`.

[`RawFd`]: https://doc.rust-lang.org/stable/std/os/unix/io/type.RawFd.html
上级 ad88831c
......@@ -24,9 +24,14 @@
pub trait AsRawFd {
/// Extracts the raw file descriptor.
///
/// This method does **not** pass ownership of the raw file descriptor
/// to the caller. The descriptor is only guaranteed to be valid while
/// the original object has not yet been destroyed.
/// This function is typically used to **borrow** an owned file descriptor.
/// When used in this way, this method does **not** pass ownership of the
/// raw file descriptor to the caller, and the file descriptor is only
/// guaranteed to be valid while the original object has not yet been
/// destroyed.
///
/// However, borrowing is not strictly required. See [`AsFd::as_fd`]
/// for an API which strictly borrows a handle.
///
/// # Example
///
......@@ -55,15 +60,17 @@ pub trait FromRawFd {
/// Constructs a new instance 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.
/// This function is typically used to **consume ownership** of the
/// specified file descriptor. When used in this way, the returned object
/// will take responsibility for closing it when the object goes out of
/// scope.
///
/// However, consuming ownership is not strictly required. See
/// [`FromFd::from_fd`] for an API which strictly consumes ownership.
///
/// 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.
/// # Safety
///
/// The `fd` passed in must be a valid an open file descriptor.
///
/// # Example
///
......@@ -94,9 +101,12 @@ pub trait FromRawFd {
pub trait IntoRawFd {
/// Consumes this object, returning the raw underlying file descriptor.
///
/// This function **transfers ownership** of the underlying file descriptor
/// to the caller. Callers are then the unique owners of the file descriptor
/// and must close the descriptor once it's no longer needed.
/// This function is typically used to **transfer ownership** of the underlying
/// file descriptor to the caller. When used in this way, callers are then the unique
/// owners of the file descriptor and must close it once it's no longer needed.
///
/// However, transferring ownership is not strictly required. See
/// [`IntoFd::into_fd`] for an API which strictly transfers ownership.
///
/// # Example
///
......
......@@ -210,29 +210,13 @@ fn into_raw_handle(self) -> RawHandle {
}
impl FromRawHandle for OwnedHandle {
/// Constructs a new instance of `Self` from the given raw handle.
///
/// # Safety
///
/// The resource pointed to by `handle` must be open and suitable for
/// assuming ownership. The resource must not require any cleanup other
/// than `CloseHandle`.
///
/// In particular, it must not be used with handles to open registry
/// keys which need to be closed with [`RegCloseKey`] instead.
///
/// Note that it *may* have the value `INVALID_HANDLE_VALUE` (-1), which is
/// sometimes a valid handle value. See [here] for the full story.
///
/// [`RegCloseKey`]: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regclosekey
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
#[inline]
unsafe fn from_raw_handle(handle: RawHandle) -> Self {
Self { handle }
}
}
impl FromRawHandle for HandleOrNull {
impl HandleOrNull {
/// Constructs a new instance of `Self` from the given `RawHandle` returned
/// from a Windows API that uses null to indicate failure, such as
/// `CreateThread`.
......@@ -242,9 +226,9 @@ impl FromRawHandle for HandleOrNull {
///
/// # Safety
///
/// The resource pointed to by `handle` must be either open and otherwise
/// unowned, or null. Note that not all Windows APIs use null for errors;
/// see [here] for the full story.
/// The passed `handle` value must either satisfy the safety requirements
/// of [`FromRawHandle::from_raw_handle`], or be null. Note that not all
/// Windows APIs use null for errors; see [here] for the full story.
///
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
#[inline]
......@@ -253,7 +237,7 @@ unsafe fn from_raw_handle(handle: RawHandle) -> Self {
}
}
impl FromRawHandle for HandleOrInvalid {
impl HandleOrInvalid {
/// Constructs a new instance of `Self` from the given `RawHandle` returned
/// from a Windows API that uses `INVALID_HANDLE_VALUE` to indicate
/// failure, such as `CreateFileW`.
......@@ -263,10 +247,10 @@ impl FromRawHandle for HandleOrInvalid {
///
/// # Safety
///
/// The resource pointed to by `handle` must be either open and otherwise
/// unowned, null, or equal to `INVALID_HANDLE_VALUE` (-1). Note that not
/// all Windows APIs use `INVALID_HANDLE_VALUE` for errors; see [here] for
/// the full story.
/// The passed `handle` value must either satisfy the safety requirements
/// of [`FromRawHandle::from_raw_handle`], or be
/// `INVALID_HANDLE_VALUE` (-1). Note that not all Windows APIs use
/// `INVALID_HANDLE_VALUE` for errors; see [here] for the full story.
///
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
#[inline]
......
......@@ -22,7 +22,15 @@
/// Extracts raw handles.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawHandle {
/// Extracts the raw handle, without taking any ownership.
/// Extracts the raw handle.
///
/// This function is typically used to **borrow** an owned handle.
/// When used in this way, this method does **not** pass ownership of the
/// raw handle to the caller, and the handle is only guaranteed
/// to be valid while the original object has not yet been destroyed.
///
/// However, borrowing is not strictly required. See [`AsHandle::as_handle`]
/// for an API which strictly borrows a handle.
#[stable(feature = "rust1", since = "1.0.0")]
fn as_raw_handle(&self) -> RawHandle;
}
......@@ -32,15 +40,29 @@ pub trait AsRawHandle {
pub trait FromRawHandle {
/// Constructs 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.
/// This function is typically used to **consume ownership** of the handle
/// given, passing responsibility for closing the handle to the returned
/// object. When used in this way, the returned object
/// will take responsibility for closing it when the object goes out of
/// scope.
///
/// However, consuming ownership is not strictly required. See
/// [`FromHandle::from_handle`] for an API which strictly consumes ownership.
///
/// # Safety
///
/// 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.
/// The `handle` passed in must:
/// - be a valid an open handle,
/// - be a handle opened for synchronous I/O, *without* the
/// `FILE_FLAG_OVERLAPPED` flag, and
/// - be a handle for a resource that may be freed via [`CloseHandle`]
/// (as opposed to `RegCloseKey` or other close functions).
///
/// Note that the handle *may* have the value `INVALID_HANDLE_VALUE` (-1),
/// which is sometimes a valid handle value. See [here] for the full story.
///
/// [`CloseHandle`]: https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle
/// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443
#[stable(feature = "from_raw_os", since = "1.1.0")]
unsafe fn from_raw_handle(handle: RawHandle) -> Self;
}
......@@ -51,9 +73,12 @@ pub trait FromRawHandle {
pub trait IntoRawHandle {
/// Consumes this object, returning the raw underlying handle.
///
/// This function **transfers ownership** of the underlying handle to the
/// caller. Callers are then the unique owners of the handle and must close
/// it once it's no longer needed.
/// This function is typically used to **transfer ownership** of the underlying
/// handle to the caller. When used in this way, callers are then the unique
/// owners of the handle and must close it once it's no longer needed.
///
/// However, transferring ownership is not strictly required. See
/// [`IntoHandle::into_handle`] for an API which strictly transfers ownership.
#[stable(feature = "into_raw_os", since = "1.4.0")]
fn into_raw_handle(self) -> RawHandle;
}
......@@ -130,7 +155,15 @@ fn into_raw_handle(self) -> RawHandle {
/// Extracts raw sockets.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawSocket {
/// Extracts the underlying raw socket from this object.
/// Extracts the raw socket.
///
/// This function is typically used to **borrow** an owned socket.
/// When used in this way, this method does **not** pass ownership of the
/// raw socket to the caller, and the socket is only guaranteed
/// to be valid while the original object has not yet been destroyed.
///
/// However, borrowing is not strictly required. See [`AsSocket::as_socket`]
/// for an API which strictly borrows a socket.
#[stable(feature = "rust1", since = "1.0.0")]
fn as_raw_socket(&self) -> RawSocket;
}
......@@ -138,16 +171,24 @@ pub trait AsRawSocket {
/// Creates I/O objects from raw sockets.
#[stable(feature = "from_raw_os", since = "1.1.0")]
pub trait FromRawSocket {
/// Creates a new I/O object from the given raw socket.
/// Constructs a new I/O object from the specified raw socket.
///
/// This function is typically used to **consume ownership** of the socket
/// given, passing responsibility for closing the socket to the returned
/// object. When used in this way, the returned object
/// will take responsibility for closing it when the object goes out of
/// scope.
///
/// This function will **consume ownership** of the socket provided and
/// it will be closed when the returned object goes out of scope.
/// However, consuming ownership is not strictly required. See
/// [`FromSocket::from_socket`] for an API which strictly consumes ownership.
///
/// 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.
/// # Safety
///
/// The `socket` passed in must:
/// - be a valid an open socket,
/// - be a handle for a resource that may be freed via [`closesocket`].
///
/// [`closesocket`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-closesocket
#[stable(feature = "from_raw_os", since = "1.1.0")]
unsafe fn from_raw_socket(sock: RawSocket) -> Self;
}
......@@ -158,9 +199,12 @@ pub trait FromRawSocket {
pub trait IntoRawSocket {
/// Consumes this object, returning the raw underlying socket.
///
/// This function **transfers ownership** of the underlying socket to the
/// caller. Callers are then the unique owners of the socket and must close
/// it once it's no longer needed.
/// This function is typically used to **transfer ownership** of the underlying
/// socket to the caller. When used in this way, callers are then the unique
/// owners of the socket and must close it once it's no longer needed.
///
/// However, transferring ownership is not strictly required. See
/// [`IntoSocket::into_socket`] for an API which strictly transfers ownership.
#[stable(feature = "into_raw_os", since = "1.4.0")]
fn into_raw_socket(self) -> RawSocket;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册