From 8bec57a00d3a20598746971dab9f81031f009a97 Mon Sep 17 00:00:00 2001 From: Vladimir Shiryaev Date: Thu, 24 Sep 2026 17:43:40 -0700 Subject: [PATCH 1/2] [llvm][Support] Use ::closesocket for native sockets on Windows Calling ::close on a Windows SOCKET that has not been converted with _open_osfhandle crashes and aborts the process instead of returning an error. Use ::closesocket on Windows for those sockets, and keep ::close on POSIX. --- llvm/lib/Support/raw_socket_stream.cpp | 33 +++++++++++++++---- .../Support/raw_socket_stream_test.cpp | 10 ++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Support/raw_socket_stream.cpp b/llvm/lib/Support/raw_socket_stream.cpp index cdf793c8958f9..6e78a17a968e3 100644 --- a/llvm/lib/Support/raw_socket_stream.cpp +++ b/llvm/lib/Support/raw_socket_stream.cpp @@ -61,6 +61,20 @@ static std::error_code getLastSocketErrorCode() { #endif } +#ifdef _WIN32 +using NativeSocket = SOCKET; +#else +using NativeSocket = int; +#endif + +static int closeSocket(NativeSocket Socket) { +#ifdef _WIN32 + return ::closesocket(Socket); +#else + return ::close(Socket); +#endif +} + static Expected setSocketAddr(StringRef SocketPath) { struct sockaddr_un Addr; memset(&Addr, 0, sizeof(Addr)); @@ -97,13 +111,16 @@ static Expected getSocketFD(StringRef SocketPath) { setsockopt(Socket, SOL_SOCKET, SO_PEERCRED, NULL, 0); #endif Expected Addr = setSocketAddr(SocketPath); - if (!Addr) + if (!Addr) { + closeSocket(Socket); return Addr.takeError(); + } if (::connect(Socket, (struct sockaddr *)&*Addr, sizeof(*Addr)) == -1) { - ::close(Socket); - return llvm::make_error(getLastSocketErrorCode(), - "Connect socket failed"); + // Grab the error code before closing, which may overwrite it. + std::error_code EC = getLastSocketErrorCode(); + closeSocket(Socket); + return llvm::make_error(EC, "Connect socket failed"); } #ifdef _WIN32 @@ -177,13 +194,15 @@ Expected ListeningSocket::createUnix(StringRef SocketPath, setsockopt(Socket, SOL_SOCKET, SO_PEERCRED, NULL, 0); #endif Expected Addr = setSocketAddr(SocketPath); - if (!Addr) + if (!Addr) { + closeSocket(Socket); return Addr.takeError(); + } if (::bind(Socket, (struct sockaddr *)&*Addr, sizeof(*Addr)) == -1) { - // Grab error code from call to ::bind before calling ::close + // Grab error code from call to ::bind before closing the socket std::error_code EC = getLastSocketErrorCode(); - ::close(Socket); + closeSocket(Socket); return llvm::make_error(EC, "Bind error"); } diff --git a/llvm/unittests/Support/raw_socket_stream_test.cpp b/llvm/unittests/Support/raw_socket_stream_test.cpp index 293be53a25d21..673ef4f6b3e9f 100644 --- a/llvm/unittests/Support/raw_socket_stream_test.cpp +++ b/llvm/unittests/Support/raw_socket_stream_test.cpp @@ -99,6 +99,16 @@ TEST_F(raw_socket_streamTest, ACCEPT_WITH_TIMEOUT) { std::errc::timed_out); } +TEST_F(raw_socket_streamTest, CONNECT_FAILURE_RETURNS_ERROR) { + ServerListener->shutdown(); + + // Connecting to a closed or nonexistent socket should return an error, + // not terminate the process while cleaning up the temporary native socket. + Expected> MaybeClient = + raw_socket_stream::createConnectedUnix(SocketPath); + ASSERT_THAT_EXPECTED(MaybeClient, llvm::Failed()); +} + TEST_F(raw_socket_streamTest, ACCEPT_WITH_SHUTDOWN) { // Create a separate thread to close the socket after a delay. Simulates a // signal handler calling ServerListener::shutdown From d2bb12ed27f4e0c92eaa00da776b17a71490bad4 Mon Sep 17 00:00:00 2001 From: Vladimir Shiryaev Date: Fri, 25 Sep 2026 10:13:51 -0700 Subject: [PATCH 2/2] [llvm][Support] Unify NativeSocket creation around INVALID_SOCKET so socket creation and the failure check are no longer duplicated --- llvm/lib/Support/raw_socket_stream.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Support/raw_socket_stream.cpp b/llvm/lib/Support/raw_socket_stream.cpp index 6e78a17a968e3..d708b35673c7c 100644 --- a/llvm/lib/Support/raw_socket_stream.cpp +++ b/llvm/lib/Support/raw_socket_stream.cpp @@ -65,6 +65,7 @@ static std::error_code getLastSocketErrorCode() { using NativeSocket = SOCKET; #else using NativeSocket = int; +#define INVALID_SOCKET -1 #endif static int closeSocket(NativeSocket Socket) { @@ -90,13 +91,8 @@ static Expected setSocketAddr(StringRef SocketPath) { } static Expected getSocketFD(StringRef SocketPath) { -#ifdef _WIN32 - SOCKET Socket = socket(AF_UNIX, SOCK_STREAM, 0); + NativeSocket Socket = socket(AF_UNIX, SOCK_STREAM, 0); if (Socket == INVALID_SOCKET) { -#else - int Socket = socket(AF_UNIX, SOCK_STREAM, 0); - if (Socket == -1) { -#endif // _WIN32 return llvm::make_error(getLastSocketErrorCode(), "Create socket failed"); } @@ -175,12 +171,9 @@ Expected ListeningSocket::createUnix(StringRef SocketPath, #ifdef _WIN32 WSABalancer _; - SOCKET Socket = socket(AF_UNIX, SOCK_STREAM, 0); +#endif // _WIN32 + NativeSocket Socket = socket(AF_UNIX, SOCK_STREAM, 0); if (Socket == INVALID_SOCKET) -#else - int Socket = socket(AF_UNIX, SOCK_STREAM, 0); - if (Socket == -1) -#endif return llvm::make_error(getLastSocketErrorCode(), "socket create failed");