aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/net
diff options
context:
space:
mode:
authorFenrir <[email protected]>2018-04-14 20:02:05 -0600
committerFenrir <[email protected]>2018-04-21 16:35:01 -0600
commitb330206f5590d88a2f995321d2ea847ded951d1d (patch)
tree4fecd0ca00b754c494e96b13e9837db48de93109 /ctr-std/src/net
parentMove more implementation details to `imp` module (diff)
downloadctru-rs-b330206f5590d88a2f995321d2ea847ded951d1d.tar.xz
ctru-rs-b330206f5590d88a2f995321d2ea847ded951d1d.zip
Update for Rust nightly 2018-04-19
Diffstat (limited to 'ctr-std/src/net')
-rw-r--r--ctr-std/src/net/addr.rs14
-rw-r--r--ctr-std/src/net/ip.rs95
-rw-r--r--ctr-std/src/net/mod.rs17
-rw-r--r--ctr-std/src/net/parser.rs19
-rw-r--r--ctr-std/src/net/tcp.rs83
-rw-r--r--ctr-std/src/net/udp.rs87
6 files changed, 269 insertions, 46 deletions
diff --git a/ctr-std/src/net/addr.rs b/ctr-std/src/net/addr.rs
index 1ca7e66..bc2c9f5 100644
--- a/ctr-std/src/net/addr.rs
+++ b/ctr-std/src/net/addr.rs
@@ -12,7 +12,9 @@ use fmt;
use hash;
use io;
use mem;
-use net::{lookup_host, ntoh, hton, IpAddr, Ipv4Addr, Ipv6Addr};
+use net::{ntoh, hton, IpAddr, Ipv4Addr, Ipv6Addr};
+#[allow(deprecated)]
+use net::lookup_host;
use option;
use sys::net::netc as c;
use sys_common::{FromInner, AsInner, IntoInner};
@@ -26,6 +28,9 @@ use slice;
/// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and
/// [`SocketAddrV6`]'s respective documentation for more details.
///
+/// The size of a `SocketAddr` instance may vary depending on the target operating
+/// system.
+///
/// [IP address]: ../../std/net/enum.IpAddr.html
/// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
/// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
@@ -59,6 +64,9 @@ pub enum SocketAddr {
///
/// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
///
+/// The size of a `SocketAddrV4` struct may vary depending on the target operating
+/// system.
+///
/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
/// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
@@ -86,6 +94,9 @@ pub struct SocketAddrV4 { inner: c::sockaddr_in }
///
/// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
///
+/// The size of a `SocketAddrV6` struct may vary depending on the target operating
+/// system.
+///
/// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
/// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
@@ -845,6 +856,7 @@ impl ToSocketAddrs for (Ipv6Addr, u16) {
}
}
+#[allow(deprecated)]
fn resolve_socket_addr(s: &str, p: u16) -> io::Result<vec::IntoIter<SocketAddr>> {
let ips = lookup_host(s)?;
let v: Vec<_> = ips.map(|mut a| { a.set_port(p); a }).collect();
diff --git a/ctr-std/src/net/ip.rs b/ctr-std/src/net/ip.rs
index 0d73a6f..fcec8d0 100644
--- a/ctr-std/src/net/ip.rs
+++ b/ctr-std/src/net/ip.rs
@@ -26,6 +26,9 @@ use sys_common::{AsInner, FromInner};
/// This enum can contain either an [`Ipv4Addr`] or an [`Ipv6Addr`], see their
/// respective documentation for more details.
///
+/// The size of an `IpAddr` instance may vary depending on the target operating
+/// system.
+///
/// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
/// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
///
@@ -61,6 +64,9 @@ pub enum IpAddr {
///
/// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
///
+/// The size of an `Ipv4Addr` struct may vary depending on the target operating
+/// system.
+///
/// [IETF RFC 791]: https://tools.ietf.org/html/rfc791
/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
///
@@ -93,6 +99,9 @@ pub struct Ipv4Addr {
///
/// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
///
+/// The size of an `Ipv6Addr` struct may vary depending on the target operating
+/// system.
+///
/// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
///
@@ -769,7 +778,16 @@ impl FromInner<c::in_addr> for Ipv4Addr {
#[stable(feature = "ip_u32", since = "1.1.0")]
impl From<Ipv4Addr> for u32 {
- /// It performs the conversion in network order (big-endian).
+ /// Convert an `Ipv4Addr` into a host byte order `u32`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::net::Ipv4Addr;
+ ///
+ /// let addr = Ipv4Addr::new(13, 12, 11, 10);
+ /// assert_eq!(0x0d0c0b0au32, u32::from(addr));
+ /// ```
fn from(ip: Ipv4Addr) -> u32 {
let ip = ip.octets();
((ip[0] as u32) << 24) + ((ip[1] as u32) << 16) + ((ip[2] as u32) << 8) + (ip[3] as u32)
@@ -778,7 +796,16 @@ impl From<Ipv4Addr> for u32 {
#[stable(feature = "ip_u32", since = "1.1.0")]
impl From<u32> for Ipv4Addr {
- /// It performs the conversion in network order (big-endian).
+ /// Convert a host byte order `u32` into an `Ipv4Addr`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::net::Ipv4Addr;
+ ///
+ /// let addr = Ipv4Addr::from(0x0d0c0b0au32);
+ /// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr);
+ /// ```
fn from(ip: u32) -> Ipv4Addr {
Ipv4Addr::new((ip >> 24) as u8, (ip >> 16) as u8, (ip >> 8) as u8, ip as u8)
}
@@ -786,6 +813,14 @@ impl From<u32> for Ipv4Addr {
#[stable(feature = "from_slice_v4", since = "1.9.0")]
impl From<[u8; 4]> for Ipv4Addr {
+ /// # Examples
+ ///
+ /// ```
+ /// use std::net::Ipv4Addr;
+ ///
+ /// let addr = Ipv4Addr::from([13u8, 12u8, 11u8, 10u8]);
+ /// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr);
+ /// ```
fn from(octets: [u8; 4]) -> Ipv4Addr {
Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3])
}
@@ -793,6 +828,16 @@ impl From<[u8; 4]> for Ipv4Addr {
#[stable(feature = "ip_from_slice", since = "1.17.0")]
impl From<[u8; 4]> for IpAddr {
+ /// Create an `IpAddr::V4` from a four element byte array.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::net::{IpAddr, Ipv4Addr};
+ ///
+ /// let addr = IpAddr::from([13u8, 12u8, 11u8, 10u8]);
+ /// assert_eq!(IpAddr::V4(Ipv4Addr::new(13, 12, 11, 10)), addr);
+ /// ```
fn from(octets: [u8; 4]) -> IpAddr {
IpAddr::V4(Ipv4Addr::from(octets))
}
@@ -1346,7 +1391,7 @@ impl FromInner<c::in6_addr> for Ipv6Addr {
}
}
-#[unstable(feature = "i128", issue = "35118")]
+#[stable(feature = "i128", since = "1.26.0")]
impl From<Ipv6Addr> for u128 {
fn from(ip: Ipv6Addr) -> u128 {
let ip = ip.segments();
@@ -1355,7 +1400,7 @@ impl From<Ipv6Addr> for u128 {
((ip[6] as u128) << 16) + (ip[7] as u128)
}
}
-#[unstable(feature = "i128", issue = "35118")]
+#[stable(feature = "i128", since = "1.26.0")]
impl From<u128> for Ipv6Addr {
fn from(ip: u128) -> Ipv6Addr {
Ipv6Addr::new(
@@ -1386,6 +1431,27 @@ impl From<[u16; 8]> for Ipv6Addr {
#[stable(feature = "ip_from_slice", since = "1.17.0")]
impl From<[u8; 16]> for IpAddr {
+ /// Create an `IpAddr::V6` from a sixteen element byte array.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::net::{IpAddr, Ipv6Addr};
+ ///
+ /// let addr = IpAddr::from([
+ /// 25u8, 24u8, 23u8, 22u8, 21u8, 20u8, 19u8, 18u8,
+ /// 17u8, 16u8, 15u8, 14u8, 13u8, 12u8, 11u8, 10u8,
+ /// ]);
+ /// assert_eq!(
+ /// IpAddr::V6(Ipv6Addr::new(
+ /// 0x1918, 0x1716,
+ /// 0x1514, 0x1312,
+ /// 0x1110, 0x0f0e,
+ /// 0x0d0c, 0x0b0a
+ /// )),
+ /// addr
+ /// );
+ /// ```
fn from(octets: [u8; 16]) -> IpAddr {
IpAddr::V6(Ipv6Addr::from(octets))
}
@@ -1393,6 +1459,27 @@ impl From<[u8; 16]> for IpAddr {
#[stable(feature = "ip_from_slice", since = "1.17.0")]
impl From<[u16; 8]> for IpAddr {
+ /// Create an `IpAddr::V6` from an eight element 16-bit array.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::net::{IpAddr, Ipv6Addr};
+ ///
+ /// let addr = IpAddr::from([
+ /// 525u16, 524u16, 523u16, 522u16,
+ /// 521u16, 520u16, 519u16, 518u16,
+ /// ]);
+ /// assert_eq!(
+ /// IpAddr::V6(Ipv6Addr::new(
+ /// 0x20d, 0x20c,
+ /// 0x20b, 0x20a,
+ /// 0x209, 0x208,
+ /// 0x207, 0x206
+ /// )),
+ /// addr
+ /// );
+ /// ```
fn from(segments: [u16; 8]) -> IpAddr {
IpAddr::V6(Ipv6Addr::from(segments))
}
diff --git a/ctr-std/src/net/mod.rs b/ctr-std/src/net/mod.rs
index 9fcb93e..b0d5e56 100644
--- a/ctr-std/src/net/mod.rs
+++ b/ctr-std/src/net/mod.rs
@@ -134,12 +134,15 @@ fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
iterator and returning socket \
addresses",
issue = "27705")]
+#[rustc_deprecated(since = "1.25.0", reason = "Use the ToSocketAddrs trait instead")]
pub struct LookupHost(net_imp::LookupHost);
#[unstable(feature = "lookup_host", reason = "unsure about the returned \
iterator and returning socket \
addresses",
issue = "27705")]
+#[rustc_deprecated(since = "1.25.0", reason = "Use the ToSocketAddrs trait instead")]
+#[allow(deprecated)]
impl Iterator for LookupHost {
type Item = SocketAddr;
fn next(&mut self) -> Option<SocketAddr> { self.0.next() }
@@ -149,6 +152,8 @@ impl Iterator for LookupHost {
iterator and returning socket \
addresses",
issue = "27705")]
+#[rustc_deprecated(since = "1.25.0", reason = "Use the ToSocketAddrs trait instead")]
+#[allow(deprecated)]
impl fmt::Debug for LookupHost {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("LookupHost { .. }")
@@ -170,17 +175,19 @@ impl fmt::Debug for LookupHost {
///
/// use std::net;
///
-/// # fn foo() -> std::io::Result<()> {
-/// for host in net::lookup_host("rust-lang.org")? {
-/// println!("found address: {}", host);
+/// fn main() -> std::io::Result<()> {
+/// for host in net::lookup_host("rust-lang.org")? {
+/// println!("found address: {}", host);
+/// }
+/// Ok(())
/// }
-/// # Ok(())
-/// # }
/// ```
#[unstable(feature = "lookup_host", reason = "unsure about the returned \
iterator and returning socket \
addresses",
issue = "27705")]
+#[rustc_deprecated(since = "1.25.0", reason = "Use the ToSocketAddrs trait instead")]
+#[allow(deprecated)]
pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
net_imp::lookup_host(host).map(LookupHost)
}
diff --git a/ctr-std/src/net/parser.rs b/ctr-std/src/net/parser.rs
index 261d44e..ae5037c 100644
--- a/ctr-std/src/net/parser.rs
+++ b/ctr-std/src/net/parser.rs
@@ -372,6 +372,25 @@ impl FromStr for SocketAddr {
/// [`IpAddr`], [`Ipv4Addr`], [`Ipv6Addr`], [`SocketAddr`], [`SocketAddrV4`], and
/// [`SocketAddrV6`].
///
+/// # Potential causes
+///
+/// `AddrParseError` may be thrown because the provided string does not parse as the given type,
+/// often because it includes information only handled by a different address type.
+///
+/// ```should_panic
+/// use std::net::IpAddr;
+/// let _foo: IpAddr = "127.0.0.1:8080".parse().expect("Cannot handle the socket port");
+/// ```
+///
+/// [`IpAddr`] doesn't handle the port. Use [`SocketAddr`] instead.
+///
+/// ```
+/// use std::net::SocketAddr;
+///
+/// // No problem, the `panic!` message has disappeared.
+/// let _foo: SocketAddr = "127.0.0.1:8080".parse().expect("unreachable panic");
+/// ```
+///
/// [`FromStr`]: ../../std/str/trait.FromStr.html
/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
/// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
diff --git a/ctr-std/src/net/tcp.rs b/ctr-std/src/net/tcp.rs
index 78235ea..0f60b5b 100644
--- a/ctr-std/src/net/tcp.rs
+++ b/ctr-std/src/net/tcp.rs
@@ -72,7 +72,7 @@ pub struct TcpStream(net_imp::TcpStream);
///
/// # Examples
///
-/// ```
+/// ```no_run
/// # use std::io;
/// use std::net::{TcpListener, TcpStream};
///
@@ -80,15 +80,15 @@ pub struct TcpStream(net_imp::TcpStream);
/// // ...
/// }
///
-/// # fn process() -> io::Result<()> {
-/// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
+/// fn main() -> io::Result<()> {
+/// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
///
-/// // accept connections and process them serially
-/// for stream in listener.incoming() {
-/// handle_client(stream?);
+/// // accept connections and process them serially
+/// for stream in listener.incoming() {
+/// handle_client(stream?);
+/// }
+/// Ok(())
/// }
-/// # Ok(())
-/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub struct TcpListener(net_imp::TcpListener);
@@ -259,19 +259,21 @@ impl TcpStream {
/// Sets the read timeout to the timeout specified.
///
/// If the value specified is [`None`], then [`read`] calls will block
- /// indefinitely. It is an error to pass the zero `Duration` to this
- /// method.
+ /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
+ /// passed to this method.
///
- /// # Note
+ /// # Platform-specific behavior
///
/// Platforms may return a different error code whenever a read times out as
/// a result of setting this option. For example Unix typically returns an
/// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
+ /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
/// [`read`]: ../../std/io/trait.Read.html#tymethod.read
/// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
/// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
+ /// [`Duration`]: ../../std/time/struct.Duration.html
///
/// # Examples
///
@@ -282,6 +284,20 @@ impl TcpStream {
/// .expect("Couldn't connect to the server...");
/// stream.set_read_timeout(None).expect("set_read_timeout call failed");
/// ```
+ ///
+ /// An [`Err`] is returned if the zero [`Duration`] is passed to this
+ /// method:
+ ///
+ /// ```no_run
+ /// use std::io;
+ /// use std::net::TcpStream;
+ /// use std::time::Duration;
+ ///
+ /// let stream = TcpStream::connect("127.0.0.1:8080").unwrap();
+ /// let result = stream.set_read_timeout(Some(Duration::new(0, 0)));
+ /// let err = result.unwrap_err();
+ /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
+ /// ```
#[stable(feature = "socket_timeout", since = "1.4.0")]
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
self.0.set_read_timeout(dur)
@@ -290,16 +306,17 @@ impl TcpStream {
/// Sets the write timeout to the timeout specified.
///
/// If the value specified is [`None`], then [`write`] calls will block
- /// indefinitely. It is an error to pass the zero [`Duration`] to this
- /// method.
+ /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
+ /// passed to this method.
///
- /// # Note
+ /// # Platform-specific behavior
///
/// Platforms may return a different error code whenever a write times out
/// as a result of setting this option. For example Unix typically returns
/// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
+ /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
/// [`write`]: ../../std/io/trait.Write.html#tymethod.write
/// [`Duration`]: ../../std/time/struct.Duration.html
/// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
@@ -314,6 +331,20 @@ impl TcpStream {
/// .expect("Couldn't connect to the server...");
/// stream.set_write_timeout(None).expect("set_write_timeout call failed");
/// ```
+ ///
+ /// An [`Err`] is returned if the zero [`Duration`] is passed to this
+ /// method:
+ ///
+ /// ```no_run
+ /// use std::io;
+ /// use std::net::TcpStream;
+ /// use std::time::Duration;
+ ///
+ /// let stream = TcpStream::connect("127.0.0.1:8080").unwrap();
+ /// let result = stream.set_write_timeout(Some(Duration::new(0, 0)));
+ /// let err = result.unwrap_err();
+ /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
+ /// ```
#[stable(feature = "socket_timeout", since = "1.4.0")]
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
self.0.set_write_timeout(dur)
@@ -323,7 +354,7 @@ impl TcpStream {
///
/// If the timeout is [`None`], then [`read`] calls will block indefinitely.
///
- /// # Note
+ /// # Platform-specific behavior
///
/// Some platforms do not provide access to the current timeout.
///
@@ -349,7 +380,7 @@ impl TcpStream {
///
/// If the timeout is [`None`], then [`write`] calls will block indefinitely.
///
- /// # Note
+ /// # Platform-specific behavior
///
/// Some platforms do not provide access to the current timeout.
///
@@ -1545,6 +1576,26 @@ mod tests {
drop(listener);
}
+ // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
+ // when passed zero Durations
+ #[test]
+ fn test_timeout_zero_duration() {
+ let addr = next_test_ip4();
+
+ let listener = t!(TcpListener::bind(&addr));
+ let stream = t!(TcpStream::connect(&addr));
+
+ let result = stream.set_write_timeout(Some(Duration::new(0, 0)));
+ let err = result.unwrap_err();
+ assert_eq!(err.kind(), ErrorKind::InvalidInput);
+
+ let result = stream.set_read_timeout(Some(Duration::new(0, 0)));
+ let err = result.unwrap_err();
+ assert_eq!(err.kind(), ErrorKind::InvalidInput);
+
+ drop(listener);
+ }
+
#[test]
fn nodelay() {
let addr = next_test_ip4();
diff --git a/ctr-std/src/net/udp.rs b/ctr-std/src/net/udp.rs
index fc7f920..d25e299 100644
--- a/ctr-std/src/net/udp.rs
+++ b/ctr-std/src/net/udp.rs
@@ -44,22 +44,22 @@ use time::Duration;
/// ```no_run
/// use std::net::UdpSocket;
///
-/// # fn foo() -> std::io::Result<()> {
-/// {
-/// let mut socket = UdpSocket::bind("127.0.0.1:34254")?;
+/// fn main() -> std::io::Result<()> {
+/// {
+/// let mut socket = UdpSocket::bind("127.0.0.1:34254")?;
///
-/// // Receives a single datagram message on the socket. If `buf` is too small to hold
-/// // the message, it will be cut off.
-/// let mut buf = [0; 10];
-/// let (amt, src) = socket.recv_from(&mut buf)?;
+/// // Receives a single datagram message on the socket. If `buf` is too small to hold
+/// // the message, it will be cut off.
+/// let mut buf = [0; 10];
+/// let (amt, src) = socket.recv_from(&mut buf)?;
///
-/// // Redeclare `buf` as slice of the received data and send reverse data back to origin.
-/// let buf = &mut buf[..amt];
-/// buf.reverse();
-/// socket.send_to(buf, &src)?;
-/// # Ok(())
-/// } // the socket is closed here
-/// # }
+/// // Redeclare `buf` as slice of the received data and send reverse data back to origin.
+/// let buf = &mut buf[..amt];
+/// buf.reverse();
+/// socket.send_to(buf, &src)?;
+/// } // the socket is closed here
+/// Ok(())
+/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub struct UdpSocket(net_imp::UdpSocket);
@@ -228,16 +228,17 @@ impl UdpSocket {
/// Sets the read timeout to the timeout specified.
///
/// If the value specified is [`None`], then [`read`] calls will block
- /// indefinitely. It is an error to pass the zero [`Duration`] to this
- /// method.
+ /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
+ /// passed to this method.
///
- /// # Note
+ /// # Platform-specific behavior
///
/// Platforms may return a different error code whenever a read times out as
/// a result of setting this option. For example Unix typically returns an
/// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
+ /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
/// [`read`]: ../../std/io/trait.Read.html#tymethod.read
/// [`Duration`]: ../../std/time/struct.Duration.html
/// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
@@ -251,6 +252,20 @@ impl UdpSocket {
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// socket.set_read_timeout(None).expect("set_read_timeout call failed");
/// ```
+ ///
+ /// An [`Err`] is returned if the zero [`Duration`] is passed to this
+ /// method:
+ ///
+ /// ```no_run
+ /// use std::io;
+ /// use std::net::UdpSocket;
+ /// use std::time::Duration;
+ ///
+ /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
+ /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
+ /// let err = result.unwrap_err();
+ /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
+ /// ```
#[stable(feature = "socket_timeout", since = "1.4.0")]
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
self.0.set_read_timeout(dur)
@@ -259,16 +274,17 @@ impl UdpSocket {
/// Sets the write timeout to the timeout specified.
///
/// If the value specified is [`None`], then [`write`] calls will block
- /// indefinitely. It is an error to pass the zero [`Duration`] to this
- /// method.
+ /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
+ /// passed to this method.
///
- /// # Note
+ /// # Platform-specific behavior
///
/// Platforms may return a different error code whenever a write times out
/// as a result of setting this option. For example Unix typically returns
/// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
+ /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
/// [`write`]: ../../std/io/trait.Write.html#tymethod.write
/// [`Duration`]: ../../std/time/struct.Duration.html
/// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
@@ -282,6 +298,20 @@ impl UdpSocket {
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
/// socket.set_write_timeout(None).expect("set_write_timeout call failed");
/// ```
+ ///
+ /// An [`Err`] is returned if the zero [`Duration`] is passed to this
+ /// method:
+ ///
+ /// ```no_run
+ /// use std::io;
+ /// use std::net::UdpSocket;
+ /// use std::time::Duration;
+ ///
+ /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
+ /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
+ /// let err = result.unwrap_err();
+ /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
+ /// ```
#[stable(feature = "socket_timeout", since = "1.4.0")]
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
self.0.set_write_timeout(dur)
@@ -1024,6 +1054,23 @@ mod tests {
assert!(start.elapsed() > Duration::from_millis(400));
}
+ // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
+ // when passed zero Durations
+ #[test]
+ fn test_timeout_zero_duration() {
+ let addr = next_test_ip4();
+
+ let socket = t!(UdpSocket::bind(&addr));
+
+ let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
+ let err = result.unwrap_err();
+ assert_eq!(err.kind(), ErrorKind::InvalidInput);
+
+ let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
+ let err = result.unwrap_err();
+ assert_eq!(err.kind(), ErrorKind::InvalidInput);
+ }
+
#[test]
fn connect_send_recv() {
let addr = next_test_ip4();