diff options
| author | Tyler Julian <tjulian@uber.com> | 2017-01-10 19:11:56 -0800 |
|---|---|---|
| committer | Tyler Julian <tjulian@uber.com> | 2017-02-04 12:00:19 -0800 |
| commit | a40be0857c7bf48e39f815417b0b5293cd8ed1aa (patch) | |
| tree | f142739d4a6f706f583380436bcb28e4ca6f8ffd /src/libstd/sys_common | |
| parent | 9749df52b7ecfc8123e392b9d49786e2abf20320 (diff) | |
| download | rust-a40be0857c7bf48e39f815417b0b5293cd8ed1aa.tar.gz rust-a40be0857c7bf48e39f815417b0b5293cd8ed1aa.zip | |
libstd/net: Add `peek` APIs to UdpSocket and TcpStream
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.
Diffstat (limited to 'src/libstd/sys_common')
| -rw-r--r-- | src/libstd/sys_common/net.rs | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 10ad61f4c80..3cdeb511945 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -91,7 +91,7 @@ fn sockname<F>(f: F) -> io::Result<SocketAddr> } } -fn sockaddr_to_addr(storage: &c::sockaddr_storage, +pub fn sockaddr_to_addr(storage: &c::sockaddr_storage, len: usize) -> io::Result<SocketAddr> { match storage.ss_family as c_int { c::AF_INET => { @@ -222,6 +222,10 @@ impl TcpStream { self.inner.timeout(c::SO_SNDTIMEO) } + pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { + self.inner.peek(buf) + } + pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { self.inner.read(buf) } @@ -441,17 +445,11 @@ impl UdpSocket { } pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() }; - let mut addrlen = mem::size_of_val(&storage) as c::socklen_t; - let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t; + self.inner.recv_from(buf) + } - let n = cvt(unsafe { - c::recvfrom(*self.inner.as_inner(), - buf.as_mut_ptr() as *mut c_void, - len, 0, - &mut storage as *mut _ as *mut _, &mut addrlen) - })?; - Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?)) + pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + self.inner.peek_from(buf) } pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result<usize> { @@ -578,6 +576,10 @@ impl UdpSocket { self.inner.read(buf) } + pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { + self.inner.peek(buf) + } + pub fn send(&self, buf: &[u8]) -> io::Result<usize> { let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t; let ret = cvt(unsafe { |
