about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTrevor Gross <t.gross35@gmail.com>2025-09-06 14:39:04 -0400
committerGitHub <noreply@github.com>2025-09-06 14:39:04 -0400
commit31d7cbc3710148e6eb3cd9854c5dfdfa7e76b783 (patch)
treee48a4db6c14dbd5abc8dd410fe05b7c8c79adfe5
parentbea625f3275e3c897dc965ed97a1d19ef7831f01 (diff)
parent26b157572280d058c8a800e4888f4b37062eb533 (diff)
downloadrust-31d7cbc3710148e6eb3cd9854c5dfdfa7e76b783.tar.gz
rust-31d7cbc3710148e6eb3cd9854c5dfdfa7e76b783.zip
Rollup merge of #139524 - Berrysoft:cygwin-socket-ext, r=tgross35
Add socket extensions for cygwin

r? `@joboet`

* Abstract name uds addr
* quickack
* passcred
-rw-r--r--library/std/src/os/cygwin/mod.rs1
-rw-r--r--library/std/src/os/cygwin/net.rs17
-rw-r--r--library/std/src/os/mod.rs2
-rw-r--r--library/std/src/os/net/linux_ext/mod.rs4
-rw-r--r--library/std/src/os/net/mod.rs2
-rw-r--r--library/std/src/os/unix/net/addr.rs8
-rw-r--r--library/std/src/os/unix/net/ancillary.rs31
-rw-r--r--library/std/src/os/unix/net/datagram.rs52
-rw-r--r--library/std/src/os/unix/net/mod.rs6
-rw-r--r--library/std/src/os/unix/net/stream.rs26
-rw-r--r--library/std/src/os/unix/net/tests.rs27
-rw-r--r--library/std/src/sys/net/connection/socket/unix.rs12
12 files changed, 131 insertions, 57 deletions
diff --git a/library/std/src/os/cygwin/mod.rs b/library/std/src/os/cygwin/mod.rs
index 7f6d6a645c8..a295a07caac 100644
--- a/library/std/src/os/cygwin/mod.rs
+++ b/library/std/src/os/cygwin/mod.rs
@@ -1,4 +1,5 @@
 //! Cygwin-specific definitions
 #![stable(feature = "raw_ext", since = "1.1.0")]
 pub mod fs;
+pub mod net;
 pub(crate) mod raw;
diff --git a/library/std/src/os/cygwin/net.rs b/library/std/src/os/cygwin/net.rs
new file mode 100644
index 00000000000..0cccddb85d0
--- /dev/null
+++ b/library/std/src/os/cygwin/net.rs
@@ -0,0 +1,17 @@
+//! Cygwin-specific networking functionality.
+//!
+//! There are some limitations of Unix domain sockets on Cygwin:
+//! * The syscalls `accept` and `connect` need
+//! [handshake](https://inbox.sourceware.org/cygwin/Z_UERXFI1g-1v3p2@calimero.vinschen.de/T/#t).
+//! * Cannot bind to abstract addr.
+//! * Unbounded unix socket has an abstract local addr.
+//! * Doesn't support recvmsg with control data.
+
+#![stable(feature = "unix_socket_abstract", since = "1.70.0")]
+
+#[stable(feature = "unix_socket_abstract", since = "1.70.0")]
+pub use crate::os::net::linux_ext::addr::SocketAddrExt;
+#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+pub use crate::os::net::linux_ext::socket::UnixSocketExt;
+#[stable(feature = "tcp_quickack", since = "1.89.0")]
+pub use crate::os::net::linux_ext::tcp::TcpStreamExt;
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index ab7734a7952..96d9bfae8ca 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -185,5 +185,5 @@ pub mod xous;
 #[cfg(any(unix, target_os = "hermit", target_os = "trusty", target_os = "wasi", doc))]
 pub mod fd;
 
-#[cfg(any(target_os = "linux", target_os = "android", doc))]
+#[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin", doc))]
 mod net;
diff --git a/library/std/src/os/net/linux_ext/mod.rs b/library/std/src/os/net/linux_ext/mod.rs
index 3c9afe35479..f3f3fdd258c 100644
--- a/library/std/src/os/net/linux_ext/mod.rs
+++ b/library/std/src/os/net/linux_ext/mod.rs
@@ -1,6 +1,6 @@
-//! Linux and Android-specific networking functionality.
+//! Linux, Android and Cygwin-specific networking functionality.
 
-#![doc(cfg(any(target_os = "linux", target_os = "android")))]
+#![doc(cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin")))]
 
 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
 pub(crate) mod addr;
diff --git a/library/std/src/os/net/mod.rs b/library/std/src/os/net/mod.rs
index b7046dd7c59..47e69b3a260 100644
--- a/library/std/src/os/net/mod.rs
+++ b/library/std/src/os/net/mod.rs
@@ -9,5 +9,5 @@
         all(target_vendor = "fortanix", target_env = "sgx")
     )
 )))]
-#[cfg(any(target_os = "linux", target_os = "android", doc))]
+#[cfg(any(target_os = "linux", target_os = "android", target_os = "cygwin", doc))]
 pub(super) mod linux_ext;
diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs
index fd6fe72dd24..25b95014e08 100644
--- a/library/std/src/os/unix/net/addr.rs
+++ b/library/std/src/os/unix/net/addr.rs
@@ -1,6 +1,6 @@
 use crate::bstr::ByteStr;
 use crate::ffi::OsStr;
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 use crate::os::net::linux_ext;
 use crate::os::unix::ffi::OsStrExt;
 use crate::path::Path;
@@ -241,7 +241,7 @@ impl SocketAddr {
 
         // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
         if len == 0
-            || (cfg!(not(any(target_os = "linux", target_os = "android")))
+            || (cfg!(not(any(target_os = "linux", target_os = "android", target_os = "cygwin")))
                 && self.addr.sun_path[0] == 0)
         {
             AddressKind::Unnamed
@@ -256,8 +256,8 @@ impl SocketAddr {
 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
 impl Sealed for SocketAddr {}
 
-#[doc(cfg(any(target_os = "android", target_os = "linux")))]
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin")))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
 impl linux_ext::addr::SocketAddrExt for SocketAddr {
     fn as_abstract_name(&self) -> Option<&[u8]> {
diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs
index 36967fc3f98..d0984bdfb99 100644
--- a/library/std/src/os/unix/net/ancillary.rs
+++ b/library/std/src/os/unix/net/ancillary.rs
@@ -16,7 +16,8 @@ use crate::sys::net::Socket;
     not(target_os = "linux"),
     not(target_os = "android"),
     not(target_os = "netbsd"),
-    not(target_os = "freebsd")
+    not(target_os = "freebsd"),
+    not(target_os = "cygwin"),
 ))]
 #[allow(non_camel_case_types)]
 mod libc {
@@ -195,14 +196,15 @@ impl<'a, T> Iterator for AncillaryDataIter<'a, T> {
     not(target_os = "android"),
     not(target_os = "linux"),
     not(target_os = "netbsd"),
-    not(target_os = "freebsd")
+    not(target_os = "freebsd"),
+    not(target_os = "cygwin"),
 ))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 #[derive(Clone)]
 pub struct SocketCred(());
 
 /// Unix credential.
-#[cfg(any(target_os = "android", target_os = "linux",))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 #[derive(Clone)]
 pub struct SocketCred(libc::ucred);
@@ -217,8 +219,8 @@ pub struct SocketCred(libc::sockcred);
 #[derive(Clone)]
 pub struct SocketCred(libc::sockcred2);
 
-#[doc(cfg(any(target_os = "android", target_os = "linux")))]
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin")))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 impl SocketCred {
     /// Creates a Unix credential struct.
     ///
@@ -407,7 +409,8 @@ impl<'a> Iterator for ScmRights<'a> {
     not(target_os = "android"),
     not(target_os = "linux"),
     not(target_os = "netbsd"),
-    not(target_os = "freebsd")
+    not(target_os = "freebsd"),
+    not(target_os = "cygwin"),
 ))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub struct ScmCredentials<'a>(AncillaryDataIter<'a, ()>);
@@ -415,7 +418,7 @@ pub struct ScmCredentials<'a>(AncillaryDataIter<'a, ()>);
 /// This control message contains unix credentials.
 ///
 /// The level is equal to `SOL_SOCKET` and the type is equal to `SCM_CREDENTIALS` or `SCM_CREDS`.
-#[cfg(any(target_os = "android", target_os = "linux",))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::ucred>);
 
@@ -432,7 +435,8 @@ pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::sockcred>);
     target_os = "android",
     target_os = "linux",
     target_os = "netbsd",
-    target_os = "freebsd"
+    target_os = "freebsd",
+    target_os = "cygwin",
 ))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 impl<'a> Iterator for ScmCredentials<'a> {
@@ -460,7 +464,8 @@ pub enum AncillaryData<'a> {
         target_os = "android",
         target_os = "linux",
         target_os = "netbsd",
-        target_os = "freebsd"
+        target_os = "freebsd",
+        target_os = "cygwin",
     ))]
     ScmCredentials(ScmCredentials<'a>),
 }
@@ -489,7 +494,8 @@ impl<'a> AncillaryData<'a> {
         target_os = "android",
         target_os = "linux",
         target_os = "netbsd",
-        target_os = "freebsd"
+        target_os = "freebsd",
+        target_os = "cygwin",
     ))]
     unsafe fn as_credentials(data: &'a [u8]) -> Self {
         let ancillary_data_iter = AncillaryDataIter::new(data);
@@ -507,7 +513,7 @@ impl<'a> AncillaryData<'a> {
             match (*cmsg).cmsg_level {
                 libc::SOL_SOCKET => match (*cmsg).cmsg_type {
                     libc::SCM_RIGHTS => Ok(AncillaryData::as_rights(data)),
-                    #[cfg(any(target_os = "android", target_os = "linux",))]
+                    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
                     libc::SCM_CREDENTIALS => Ok(AncillaryData::as_credentials(data)),
                     #[cfg(target_os = "freebsd")]
                     libc::SCM_CREDS2 => Ok(AncillaryData::as_credentials(data)),
@@ -729,7 +735,8 @@ impl<'a> SocketAncillary<'a> {
         target_os = "android",
         target_os = "linux",
         target_os = "netbsd",
-        target_os = "freebsd"
+        target_os = "freebsd",
+        target_os = "cygwin",
     ))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn add_creds(&mut self, creds: &[SocketCred]) -> bool {
diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs
index 7735637c840..469bfbb0d83 100644
--- a/library/std/src/os/unix/net/datagram.rs
+++ b/library/std/src/os/unix/net/datagram.rs
@@ -14,9 +14,9 @@
 use libc::MSG_NOSIGNAL;
 
 use super::{SocketAddr, sockaddr_un};
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to};
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 use crate::io::{IoSlice, IoSliceMut};
 use crate::net::Shutdown;
 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
@@ -397,8 +397,14 @@ impl UnixDatagram {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "cygwin"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::{UnixDatagram, SocketAncillary, AncillaryData};
     /// use std::io::IoSliceMut;
@@ -428,7 +434,7 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux"))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn recv_vectored_with_ancillary_from(
         &self,
@@ -447,8 +453,14 @@ impl UnixDatagram {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "cygwin"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::{UnixDatagram, SocketAncillary, AncillaryData};
     /// use std::io::IoSliceMut;
@@ -478,7 +490,7 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux"))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn recv_vectored_with_ancillary(
         &self,
@@ -588,8 +600,14 @@ impl UnixDatagram {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "cygwin"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::{UnixDatagram, SocketAncillary};
     /// use std::io::IoSlice;
@@ -613,7 +631,7 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux"))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn send_vectored_with_ancillary_to<P: AsRef<Path>>(
         &self,
@@ -630,8 +648,14 @@ impl UnixDatagram {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "cygwin"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::{UnixDatagram, SocketAncillary};
     /// use std::io::IoSlice;
@@ -655,7 +679,7 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux"))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn send_vectored_with_ancillary(
         &self,
diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs
index 6cd62303a53..94523d7d1e4 100644
--- a/library/std/src/os/unix/net/mod.rs
+++ b/library/std/src/os/unix/net/mod.rs
@@ -4,8 +4,8 @@
 #![stable(feature = "unix_socket", since = "1.10.0")]
 
 mod addr;
-#[doc(cfg(any(target_os = "android", target_os = "linux")))]
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[doc(cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin")))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 mod ancillary;
 mod datagram;
 mod listener;
@@ -27,7 +27,7 @@ mod ucred;
 
 #[stable(feature = "unix_socket", since = "1.10.0")]
 pub use self::addr::*;
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub use self::ancillary::*;
 #[stable(feature = "unix_socket", since = "1.10.0")]
diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs
index 768fa77a5f8..ea4171a7d28 100644
--- a/library/std/src/os/unix/net/stream.rs
+++ b/library/std/src/os/unix/net/stream.rs
@@ -16,7 +16,7 @@ cfg_select! {
 }
 
 use super::{SocketAddr, sockaddr_un};
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
 use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to};
 #[cfg(any(
     target_os = "android",
@@ -508,8 +508,14 @@ impl UnixStream {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "cygwin"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::{UnixStream, SocketAncillary, AncillaryData};
     /// use std::io::IoSliceMut;
@@ -539,7 +545,7 @@ impl UnixStream {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux"))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn recv_vectored_with_ancillary(
         &self,
@@ -557,8 +563,14 @@ impl UnixStream {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(target_os = "android", target_os = "linux", target_os = "cygwin"),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::{UnixStream, SocketAncillary};
     /// use std::io::IoSlice;
@@ -582,7 +594,7 @@ impl UnixStream {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux"))]
+    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn send_vectored_with_ancillary(
         &self,
diff --git a/library/std/src/os/unix/net/tests.rs b/library/std/src/os/unix/net/tests.rs
index 9a88687b1df..4666b5e3c6c 100644
--- a/library/std/src/os/unix/net/tests.rs
+++ b/library/std/src/os/unix/net/tests.rs
@@ -3,6 +3,8 @@ use crate::io::prelude::*;
 use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
 #[cfg(target_os = "android")]
 use crate::os::android::net::{SocketAddrExt, UnixSocketExt};
+#[cfg(target_os = "cygwin")]
+use crate::os::cygwin::net::{SocketAddrExt, UnixSocketExt};
 #[cfg(target_os = "linux")]
 use crate::os::linux::net::{SocketAddrExt, UnixSocketExt};
 #[cfg(any(target_os = "android", target_os = "linux"))]
@@ -170,6 +172,7 @@ fn long_path() {
 #[test]
 #[cfg(not(target_os = "nto"))]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake
 fn timeouts() {
     let dir = tmpdir();
     let socket_path = dir.path().join("sock");
@@ -198,6 +201,7 @@ fn timeouts() {
 
 #[test]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake
 fn test_read_timeout() {
     let dir = tmpdir();
     let socket_path = dir.path().join("sock");
@@ -218,6 +222,7 @@ fn test_read_timeout() {
 
 #[test]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake
 fn test_read_with_timeout() {
     let dir = tmpdir();
     let socket_path = dir.path().join("sock");
@@ -246,6 +251,7 @@ fn test_read_with_timeout() {
 // when passed zero Durations
 #[test]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake
 fn test_unix_stream_timeout_zero_duration() {
     let dir = tmpdir();
     let socket_path = dir.path().join("sock");
@@ -283,6 +289,7 @@ fn test_unix_datagram() {
 
 #[test]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin autobinds an address
 fn test_unnamed_unix_datagram() {
     let dir = tmpdir();
     let path1 = dir.path().join("sock1");
@@ -326,6 +333,7 @@ fn test_unix_datagram_connect_to_recv_addr() {
 
 #[test]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin autobinds an address
 fn test_connect_unix_datagram() {
     let dir = tmpdir();
     let path1 = dir.path().join("sock1");
@@ -425,8 +433,9 @@ fn abstract_namespace_not_allowed_connect() {
     assert!(UnixStream::connect("\0asdf").is_err());
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin cannot bind to abstract addr
 fn test_abstract_stream_connect() {
     let msg1 = b"hello";
     let msg2 = b"world";
@@ -456,8 +465,9 @@ fn test_abstract_stream_connect() {
     thread.join().unwrap();
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin cannot bind to abstract addr
 fn test_abstract_stream_iter() {
     let addr = or_panic!(SocketAddr::from_abstract_name(b"hidden"));
     let listener = or_panic!(UnixListener::bind_addr(&addr));
@@ -478,8 +488,9 @@ fn test_abstract_stream_iter() {
     thread.join().unwrap();
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin cannot bind to abstract addr
 fn test_abstract_datagram_bind_send_to_addr() {
     let addr1 = or_panic!(SocketAddr::from_abstract_name(b"ns1"));
     let sock1 = or_panic!(UnixDatagram::bind_addr(&addr1));
@@ -499,8 +510,9 @@ fn test_abstract_datagram_bind_send_to_addr() {
     assert_eq!(addr.as_abstract_name().unwrap(), b"ns1");
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin cannot bind to abstract addr
 fn test_abstract_datagram_connect_addr() {
     let addr1 = or_panic!(SocketAddr::from_abstract_name(b"ns3"));
     let bsock1 = or_panic!(UnixDatagram::bind_addr(&addr1));
@@ -524,7 +536,7 @@ fn test_abstract_datagram_connect_addr() {
     or_panic!(bsock2.recv_from(&mut buf));
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
 fn test_abstract_name_too_long() {
     match SocketAddr::from_abstract_name(
@@ -538,7 +550,7 @@ fn test_abstract_name_too_long() {
     }
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
 fn test_abstract_no_pathname_and_not_unnamed() {
     let name = b"local";
@@ -669,9 +681,10 @@ fn test_send_vectored_fds_unix_stream() {
     }
 }
 
-#[cfg(any(target_os = "android", target_os = "linux"))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
 #[test]
 #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets
+#[cfg_attr(target_os = "cygwin", ignore)] // Cygwin recvmsg doesn't support Unix sockets
 fn test_send_vectored_with_ancillary_to_unix_datagram() {
     fn getpid() -> libc::pid_t {
         unsafe { libc::getpid() }
diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs
index 8b5970d1494..8216f8d2fd5 100644
--- a/library/std/src/sys/net/connection/socket/unix.rs
+++ b/library/std/src/sys/net/connection/socket/unix.rs
@@ -361,7 +361,7 @@ impl Socket {
         self.recv_from_with_flags(buf, 0)
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux"))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn recv_msg(&self, msg: &mut libc::msghdr) -> io::Result<usize> {
         let n = cvt(unsafe { libc::recvmsg(self.as_raw_fd(), msg, libc::MSG_CMSG_CLOEXEC) })?;
         Ok(n as usize)
@@ -384,7 +384,7 @@ impl Socket {
         self.0.is_write_vectored()
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux"))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn send_msg(&self, msg: &mut libc::msghdr) -> io::Result<usize> {
         let n = cvt(unsafe { libc::sendmsg(self.as_raw_fd(), msg, 0) })?;
         Ok(n as usize)
@@ -472,12 +472,12 @@ impl Socket {
         Ok(raw != 0)
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux",))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn set_quickack(&self, quickack: bool) -> io::Result<()> {
         setsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK, quickack as c_int)
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux",))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn quickack(&self) -> io::Result<bool> {
         let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK)?;
         Ok(raw != 0)
@@ -541,12 +541,12 @@ impl Socket {
         Ok(raw != 0)
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux",))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
         setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int)
     }
 
-    #[cfg(any(target_os = "android", target_os = "linux",))]
+    #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))]
     pub fn passcred(&self) -> io::Result<bool> {
         let passcred: libc::c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED)?;
         Ok(passcred != 0)