-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Add peek APIs to std::net #38983
Add peek APIs to std::net #38983
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @aturon (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
cc @rust-lang/libs, new proposed unstable APIs for UDP. |
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.
For consistency should we also be sure to add this to the TCP streams as well?
src/libstd/sys/windows/net.rs
Outdated
@@ -24,6 +24,8 @@ use sys_common::io::read_to_end_uninitialized; | |||
use sys_common::net; | |||
use time::Duration; | |||
|
|||
const MSG_PEEK: c_int = 0x2; |
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.
Can this be added to the the c
module with other windows bindings?
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.
yes, agree
src/libstd/sys_common/net.rs
Outdated
@@ -53,6 +53,8 @@ use libc::MSG_NOSIGNAL; | |||
target_os = "haiku", target_os = "bitrig")))] | |||
const MSG_NOSIGNAL: c_int = 0x0; | |||
|
|||
const MSG_PEEK: c_int = 0x2; |
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.
This seems duplicated with the Windows definition? If this is the unix definition can it be pulled from libc?
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.
Yes, let's use libc if possible. I've added the flag only very recently in rust-lang/libc#492. How is best to make this transition? Should we hold off on this PR until the next libc release?
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.
Oh you can just update the submodule in the repository
src/libstd/sys/windows/net.rs
Outdated
-1 if c::WSAGetLastError() == c::WSAESHUTDOWN => Ok(0), | ||
-1 => Err(last_error()), | ||
n => Ok(n as usize) | ||
} | ||
} | ||
} | ||
|
||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { | ||
recv_with_flags(buf, 0) |
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.
This may need to be self.recv_with_flags
src/libstd/sys/unix/ext/net.rs
Outdated
@@ -39,6 +39,8 @@ use libc::MSG_NOSIGNAL; | |||
target_os = "haiku", target_os = "bitrig")))] | |||
const MSG_NOSIGNAL: libc::c_int = 0x0; | |||
|
|||
const MSG_PEEK: libc::c_int = 0x2; |
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.
Can this be pulled from the libc crate?
src/libstd/net/udp.rs
Outdated
/// Successive calls return the same data. | ||
/// | ||
/// On success, returns the number of bytes read and the address from | ||
/// whence the data came. |
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.
Could this documentation also elaborate on how this relates to MSG_PEEK
?
Unix sockets as well. |
Removed the Last note from me: do we need to change |
Looks like a submodule update to liblibc got committed by accident. |
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.
Just a few nits about docs and tests; otherwise LGTM. Sorry for the long delay in reviewing!
@@ -296,6 +296,29 @@ impl TcpStream { | |||
self.0.write_timeout() | |||
} | |||
|
|||
/// Receives data on the socket from the remote adress to which it is |
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.
It'd be good to document the return value as well.
src/libstd/net/tcp.rs
Outdated
/// .expect("couldn't bind to address"); | ||
/// let mut buf = [0; 10]; | ||
/// let len = stream.peek(&mut buf).expect("peek failed"); | ||
/// assert_eq!(len, 10); |
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'm confused by this assertion -- I'd expect there to be no bytes for peeking?
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.
ah yeah, this probably needs some tweaking
src/libstd/net/tcp.rs
Outdated
for _ in 1..3 { | ||
assert_eq!(c.peek(&mut b).unwrap(), 1); | ||
} | ||
assert_eq!(c.read(&mut b).unwrap(), 1); |
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.
It'd be good to test a peek after this call to read
.
src/libstd/net/udp.rs
Outdated
/// Successive calls return the same data. This is accomplished by passing | ||
/// `MSG_PEEK` as a flag to the underlying `recv` system call. | ||
/// | ||
/// The `connect` method will connect this socket to a remote address. This |
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.
This bit about connect
should maybe move to a dedicated "Errors" section. I'd also suggest swapping the order of sentences here.
@@ -579,6 +603,34 @@ impl UdpSocket { | |||
self.0.recv(buf) | |||
} | |||
|
|||
/// Receives data on the socket from the remote adress to which it is |
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.
Docs should include info about the return value.
@aturon thanks! The |
Is this good to go? |
@sfackler Not yet, one of the assertions in the doc comment needs fixing still. |
@aturon I simply removed the assertion, I don't think it added much value to the documentation anyway |
Thanks! Let's send it to bors. @bors: r+ |
📌 Commit a870c1c has been approved by |
⌛ Testing commit a870c1c with merge c5d899f... |
💔 Test failed - status-appveyor |
@APTy looks like the tests may be failing on Travis? Also, could you squash down the commits as well? |
👍 Looking into the failure, will squash as well |
These methods enable socket reads without side-effects. That is, repeated calls to peek() return identical data. This is accomplished by providing the POSIX flag MSG_PEEK to the underlying socket read operations. This also moves the current implementation of recv_from out of the platform-independent sys_common and into respective sys/windows and sys/unix implementations. This allows for more platform-dependent implementations.
@bors: r=aturon |
📌 Commit a40be08 has been approved by |
Add peek APIs to std::net Adds "peek" APIs to `std::net` sockets, including: - `UdpSocket.peek()` - `UdpSocket.peek_from()` - `TcpStream.peek()` These methods enable socket reads without side-effects. That is, repeated calls to `peek()` return identical data. This is accomplished by providing the POSIX flag `MSG_PEEK` to the underlying socket read operations. This also moves the current implementation of `recv_from` out of the platform-independent `sys_common` and into respective `sys/windows` and `sys/unix` implementations. This allows for more platform-dependent implementations where necessary. Fixes rust-lang#38980
Add peek APIs to std::net Adds "peek" APIs to `std::net` sockets, including: - `UdpSocket.peek()` - `UdpSocket.peek_from()` - `TcpStream.peek()` These methods enable socket reads without side-effects. That is, repeated calls to `peek()` return identical data. This is accomplished by providing the POSIX flag `MSG_PEEK` to the underlying socket read operations. This also moves the current implementation of `recv_from` out of the platform-independent `sys_common` and into respective `sys/windows` and `sys/unix` implementations. This allows for more platform-dependent implementations where necessary. Fixes rust-lang#38980
peek
Adds "peek" APIs to
std::net
sockets, including:UdpSocket.peek()
UdpSocket.peek_from()
TcpStream.peek()
These methods enable socket reads without side-effects. That is, repeated calls to
peek()
return identical data. This is accomplished by providing the POSIX flagMSG_PEEK
to the underlying socket read operations.refactor
This also moves the current implementation of
recv_from
out of the platform-independentsys_common
and into respectivesys/windows
andsys/unix
implementations. This allows for more platform-dependent implementations where necessary.Fixes #38980