-
Notifications
You must be signed in to change notification settings - Fork 249
Implement the I/O-safety traits for Socket and SockRef #325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -37,7 +37,7 @@ use std::os::unix::ffi::OsStrExt; | |||||||||||||
) | ||||||||||||||
))] | ||||||||||||||
use std::os::unix::io::RawFd; | ||||||||||||||
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd}; | ||||||||||||||
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd}; | ||||||||||||||
#[cfg(feature = "all")] | ||||||||||||||
use std::os::unix::net::{UnixDatagram, UnixListener, UnixStream}; | ||||||||||||||
#[cfg(feature = "all")] | ||||||||||||||
|
@@ -2012,20 +2012,44 @@ impl crate::Socket { | |||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
#[cfg_attr(docsrs, doc(cfg(unix)))] | ||||||||||||||
impl AsFd for crate::Socket { | ||||||||||||||
fn as_fd(&self) -> BorrowedFd<'_> { | ||||||||||||||
// SAFETY: lifetime is bound by self. | ||||||||||||||
unsafe { BorrowedFd::borrow_raw(self.as_raw()) } | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
#[cfg_attr(docsrs, doc(cfg(unix)))] | ||||||||||||||
impl AsRawFd for crate::Socket { | ||||||||||||||
fn as_raw_fd(&self) -> c_int { | ||||||||||||||
self.as_raw() | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
#[cfg_attr(docsrs, doc(cfg(unix)))] | ||||||||||||||
impl From<crate::Socket> for OwnedFd { | ||||||||||||||
fn from(sock: crate::Socket) -> OwnedFd { | ||||||||||||||
// SAFETY: sock.into_raw() always returns a valid fd. | ||||||||||||||
unsafe { OwnedFd::from_raw_fd(sock.into_raw()) } | ||||||||||||||
Comment on lines
+2033
to
+2034
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently your There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this be ameliorated by adding an unsafe bound on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
As per the comment on the function: Lines 80 to 85 in 057f6c2
It should be marked as unsafe, but then it can be passed (easily) as a closure any more. So it should be an unsafe function, it's only not because it's an internal function. But to be clear There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I didn't actually notice that it was an internal function. |
||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
#[cfg_attr(docsrs, doc(cfg(unix)))] | ||||||||||||||
impl IntoRawFd for crate::Socket { | ||||||||||||||
fn into_raw_fd(self) -> c_int { | ||||||||||||||
self.into_raw() | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
#[cfg_attr(docsrs, doc(cfg(unix)))] | ||||||||||||||
impl From<OwnedFd> for crate::Socket { | ||||||||||||||
fn from(fd: OwnedFd) -> crate::Socket { | ||||||||||||||
// SAFETY: `OwnedFd` ensures the fd is valid. | ||||||||||||||
unsafe { crate::Socket::from_raw_fd(fd.into_raw_fd()) } | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
#[cfg_attr(docsrs, doc(cfg(unix)))] | ||||||||||||||
impl FromRawFd for crate::Socket { | ||||||||||||||
unsafe fn from_raw_fd(fd: c_int) -> crate::Socket { | ||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be careful with this kind of blanket impl. This will prevent you from implementing
From<&T>
for any other typeT
even ifT
does not implementAsSocket
. For example, the previous impl forS: AsRawSocket
would prevent you from adding theS: AsSocket
impl without the breaking change you're currently going through.In particular, this prevents you from having
From<&T>
for any type that isAsRawSocket
but isn'tAsSocket
.The impl might still be a good idea — as long as you've thought about whether this is acceptable, then that sounds good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two justifications:
T: AsRawSocket
bound is unsound. Replacing it withT: AsSocket
makes it sound. It is okay to make breading changes if they are to fix unsoundnessFrom<OwnedSocket>
bound onSocket
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know, that's why I removed the original implementation.
The concern above is acceptable because this is the only sound way to create
SockRef
,AsRaw
/AsSocket
was exactly designed for this reason.SockRef
is essentially a typeBorrowedFd
similar to whatTcpStream
is to aOwnedFd
.