about summary refs log tree commit diff
path: root/library/std/src/sys/windows
diff options
context:
space:
mode:
authoribraheemdev <ibrah1440@gmail.com>2021-08-30 13:02:15 -0400
committeribraheemdev <ibrah1440@gmail.com>2021-08-30 13:42:52 -0400
commit3b6777f1ab7952c058d69be15805a06a8ce0f1da (patch)
tree17a4583493e121efefb07ad58e1e7b711a9b93f4 /library/std/src/sys/windows
parent6cfa773583bb5123e630668f5bfe466716225546 (diff)
add `TcpStream::set_linger` and `TcpStream::linger`
Diffstat (limited to 'library/std/src/sys/windows')
-rw-r--r--library/std/src/sys/windows/c.rs8
-rw-r--r--library/std/src/sys/windows/net.rs17
2 files changed, 24 insertions, 1 deletions
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index 63f9be7b7e3..cedf389fbf5 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -197,6 +197,7 @@ pub const SOCK_DGRAM: c_int = 2;
 pub const SOCK_STREAM: c_int = 1;
 pub const SOCKET_ERROR: c_int = -1;
 pub const SOL_SOCKET: c_int = 0xffff;
+pub const SO_LINGER: c_int = 0x0080;
 pub const SO_RCVTIMEO: c_int = 0x1006;
 pub const SO_SNDTIMEO: c_int = 0x1005;
 pub const IPPROTO_IP: c_int = 0;
@@ -217,6 +218,13 @@ pub const IPV6_DROP_MEMBERSHIP: c_int = 13;
 pub const MSG_PEEK: c_int = 0x2;
 
 #[repr(C)]
+#[derive(Copy, Clone)]
+pub struct linger {
+    pub l_onoff: c_ushort,
+    pub l_linger: c_ushort,
+}
+
+#[repr(C)]
 pub struct ip_mreq {
     pub imr_multiaddr: in_addr,
     pub imr_interface: in_addr,
diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs
index 55aacb38c6f..1ad4f0c70a3 100644
--- a/library/std/src/sys/windows/net.rs
+++ b/library/std/src/sys/windows/net.rs
@@ -15,7 +15,7 @@ use crate::sys_common::net;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::time::Duration;
 
-use libc::{c_int, c_long, c_ulong};
+use libc::{c_int, c_long, c_ulong, c_ushort};
 
 pub type wrlen_t = i32;
 
@@ -446,6 +446,21 @@ impl Socket {
         cvt(result).map(drop)
     }
 
+    pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> {
+        let linger = c::linger {
+            l_onoff: linger.is_some() as c_ushort,
+            l_linger: linger.map(|dur| dur.as_secs() as c_ushort).unwrap_or_default(),
+        };
+
+        net::setsockopt(self, c::SOL_SOCKET, c::SO_LINGER, linger)
+    }
+
+    pub fn linger(&self) -> io::Result<Option<Duration>> {
+        let val: c::linger = net::getsockopt(self, c::SOL_SOCKET, c::SO_LINGER)?;
+
+        Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64)))
+    }
+
     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
         net::setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BYTE)
     }