Skip to content
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

Merged
merged 1 commit into from
Feb 5, 2017
Merged

Add peek APIs to std::net #38983

merged 1 commit into from
Feb 5, 2017

Conversation

APTy
Copy link
Contributor

@APTy APTy commented Jan 11, 2017

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 flag MSG_PEEK to the underlying socket read operations.

refactor

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 #38980

@rust-highfive
Copy link
Collaborator

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.

@aturon
Copy link
Member

aturon commented Jan 11, 2017

cc @rust-lang/libs, new proposed unstable APIs for UDP.

@aturon aturon added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Jan 11, 2017
Copy link
Member

@alexcrichton alexcrichton left a 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?

@@ -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;
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, agree

@@ -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;
Copy link
Member

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?

Copy link
Contributor Author

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?

Copy link
Member

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

-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)
Copy link
Member

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

@@ -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;
Copy link
Member

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?

/// Successive calls return the same data.
///
/// On success, returns the number of bytes read and the address from
/// whence the data came.
Copy link
Member

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?

@sfackler
Copy link
Member

Unix sockets as well.

@APTy APTy changed the title [WIP] Add peek APIs to std::net::UdpSocket [WIP] Add peek APIs to std::net Jan 12, 2017
@APTy
Copy link
Contributor Author

APTy commented Jan 13, 2017

Removed the sys/unix/ext and sys/redox partial implementations, since they seem unnecessary at the moment, but let me know if you feel otherwise.

Last note from me: do we need to change #[unstable(feature = "peek", issue = "38980")] before merge? I'm not familiar with the unstable/stable APIs process.

@APTy APTy changed the title [WIP] Add peek APIs to std::net Add peek APIs to std::net Jan 13, 2017
@aturon
Copy link
Member

aturon commented Jan 31, 2017

Looks like a submodule update to liblibc got committed by accident.

Copy link
Member

@aturon aturon left a 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
Copy link
Member

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.

/// .expect("couldn't bind to address");
/// let mut buf = [0; 10];
/// let len = stream.peek(&mut buf).expect("peek failed");
/// assert_eq!(len, 10);
Copy link
Member

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?

Copy link
Contributor Author

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

for _ in 1..3 {
assert_eq!(c.peek(&mut b).unwrap(), 1);
}
assert_eq!(c.read(&mut b).unwrap(), 1);
Copy link
Member

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.

/// 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
Copy link
Member

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
Copy link
Member

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.

@APTy
Copy link
Contributor Author

APTy commented Jan 31, 2017

@aturon thanks! The liblibc update is to take advantage of the MSG_PEEK flag platform bindings recently added. Will update tests/docs shortly!

@sfackler
Copy link
Member

sfackler commented Feb 3, 2017

Is this good to go?

@aturon
Copy link
Member

aturon commented Feb 3, 2017

@sfackler Not yet, one of the assertions in the doc comment needs fixing still.

@APTy
Copy link
Contributor Author

APTy commented Feb 3, 2017

@aturon I simply removed the assertion, I don't think it added much value to the documentation anyway

@aturon
Copy link
Member

aturon commented Feb 3, 2017

Thanks! Let's send it to bors.

@bors: r+

@bors
Copy link
Contributor

bors commented Feb 3, 2017

📌 Commit a870c1c has been approved by aturon

@bors
Copy link
Contributor

bors commented Feb 3, 2017

⌛ Testing commit a870c1c with merge c5d899f...

@bors
Copy link
Contributor

bors commented Feb 3, 2017

💔 Test failed - status-appveyor

@alexcrichton
Copy link
Member

@APTy looks like the tests may be failing on Travis? Also, could you squash down the commits as well?

@APTy
Copy link
Contributor Author

APTy commented Feb 4, 2017

👍 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.
@alexcrichton
Copy link
Member

@bors: r=aturon

@bors
Copy link
Contributor

bors commented Feb 4, 2017

📌 Commit a40be08 has been approved by aturon

frewsxcv added a commit to frewsxcv/rust that referenced this pull request Feb 5, 2017
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
frewsxcv added a commit to frewsxcv/rust that referenced this pull request Feb 5, 2017
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
bors added a commit that referenced this pull request Feb 5, 2017
@bors bors merged commit a40be08 into rust-lang:master Feb 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants