Skip to content

Commit 7857543

Browse files
authored
[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/[email protected]/T/#u
1 parent ba4bd3f commit 7857543

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

llvm/lib/Support/raw_socket_stream.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ static Expected<int> getSocketFD(StringRef SocketPath) {
8181
"Create socket failed");
8282
}
8383

84+
#ifdef __CYGWIN__
85+
// On Cygwin, UNIX sockets involve a handshake between connect and accept
86+
// to enable SO_PEERCRED/getpeereid handling. This necessitates accept being
87+
// called before connect can return, but at least the tests in
88+
// llvm/unittests/Support/raw_socket_stream_test do both on the same thread
89+
// (first connect and then accept), resulting in a deadlock. This call turns
90+
// off the handshake (and SO_PEERCRED/getpeereid support).
91+
setsockopt(Socket, SOL_SOCKET, SO_PEERCRED, NULL, 0);
92+
#endif
8493
struct sockaddr_un Addr = setSocketAddr(SocketPath);
8594
if (::connect(Socket, (struct sockaddr *)&Addr, sizeof(Addr)) == -1)
8695
return llvm::make_error<StringError>(getLastSocketErrorCode(),
@@ -147,6 +156,15 @@ Expected<ListeningSocket> ListeningSocket::createUnix(StringRef SocketPath,
147156
return llvm::make_error<StringError>(getLastSocketErrorCode(),
148157
"socket create failed");
149158

159+
#ifdef __CYGWIN__
160+
// On Cygwin, UNIX sockets involve a handshake between connect and accept
161+
// to enable SO_PEERCRED/getpeereid handling. This necessitates accept being
162+
// called before connect can return, but at least the tests in
163+
// llvm/unittests/Support/raw_socket_stream_test do both on the same thread
164+
// (first connect and then accept), resulting in a deadlock. This call turns
165+
// off the handshake (and SO_PEERCRED/getpeereid support).
166+
setsockopt(Socket, SOL_SOCKET, SO_PEERCRED, NULL, 0);
167+
#endif
150168
struct sockaddr_un Addr = setSocketAddr(SocketPath);
151169
if (::bind(Socket, (struct sockaddr *)&Addr, sizeof(Addr)) == -1) {
152170
// Grab error code from call to ::bind before calling ::close

0 commit comments

Comments
 (0)