MSYS2-packages/llvm/0008-LLVM-Cygwin-add-workaround-for-blocking-connect-acce.patch
2025-07-09 17:24:53 -07:00

61 lines
3.0 KiB
Diff

From 65255bfd31a48a78ec2334a6f9698a95ba03e757 Mon Sep 17 00:00:00 2001
From: jeremyd2019 <github@jdrake.com>
Date: Wed, 21 May 2025 22:15:21 -0700
Subject: [PATCH] [LLVM][Cygwin] add workaround for blocking connect/accept in
AF_UNIX sockets (#140353)
On Cygwin, UNIX sockets involve a handshake between connect and accept
to enable SO_PEERCRED/getpeereid handling. This necessitates accept
being called before connect can return, but at least the tests in
llvm/unittests/Support/raw_socket_stream_test do both on the same thread
(first connect and then accept), resulting in a deadlock. Add a call to
both places sockets are created that turns off the handshake (and
SO_PEERCRED/getpeereid support).
References:
* https://github.com/cygwin/cygwin/blob/cec8a6680ea1fe38f38001b06c34ae355a785209/winsup/cygwin/fhandler/socket_local.cc#L1462-L1471
* https://inbox.sourceware.org/cygwin/Z_UERXFI1g-1v3p2@calimero.vinschen.de/T/#u
---
llvm/lib/Support/raw_socket_stream.cpp | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/llvm/lib/Support/raw_socket_stream.cpp b/llvm/lib/Support/raw_socket_stream.cpp
index 7a4be5759f..fd1c681672 100644
--- a/llvm/lib/Support/raw_socket_stream.cpp
+++ b/llvm/lib/Support/raw_socket_stream.cpp
@@ -81,6 +81,15 @@ static Expected<int> getSocketFD(StringRef SocketPath) {
"Create socket failed");
}
+#ifdef __CYGWIN__
+ // On Cygwin, UNIX sockets involve a handshake between connect and accept
+ // to enable SO_PEERCRED/getpeereid handling. This necessitates accept being
+ // called before connect can return, but at least the tests in
+ // llvm/unittests/Support/raw_socket_stream_test do both on the same thread
+ // (first connect and then accept), resulting in a deadlock. This call turns
+ // off the handshake (and SO_PEERCRED/getpeereid support).
+ setsockopt(Socket, SOL_SOCKET, SO_PEERCRED, NULL, 0);
+#endif
struct sockaddr_un Addr = setSocketAddr(SocketPath);
if (::connect(Socket, (struct sockaddr *)&Addr, sizeof(Addr)) == -1)
return llvm::make_error<StringError>(getLastSocketErrorCode(),
@@ -147,6 +156,15 @@ Expected<ListeningSocket> ListeningSocket::createUnix(StringRef SocketPath,
return llvm::make_error<StringError>(getLastSocketErrorCode(),
"socket create failed");
+#ifdef __CYGWIN__
+ // On Cygwin, UNIX sockets involve a handshake between connect and accept
+ // to enable SO_PEERCRED/getpeereid handling. This necessitates accept being
+ // called before connect can return, but at least the tests in
+ // llvm/unittests/Support/raw_socket_stream_test do both on the same thread
+ // (first connect and then accept), resulting in a deadlock. This call turns
+ // off the handshake (and SO_PEERCRED/getpeereid support).
+ setsockopt(Socket, SOL_SOCKET, SO_PEERCRED, NULL, 0);
+#endif
struct sockaddr_un Addr = setSocketAddr(SocketPath);
if (::bind(Socket, (struct sockaddr *)&Addr, sizeof(Addr)) == -1) {
// Grab error code from call to ::bind before calling ::close
--
2.50.1.windows.1