[llvm] d359e9d - [llvm][Support] Use ::closesocket for native sockets on Windows (#226613)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 28 08:57:34 PDT 2026


Author: Vladimir Shiryaev
Date: 2026-09-28T19:57:27+04:00
New Revision: d359e9d80b4baaa2699ed5fc613533a6a147e188

URL: https://github.com/llvm/llvm-project/commit/d359e9d80b4baaa2699ed5fc613533a6a147e188
DIFF: https://github.com/llvm/llvm-project/commit/d359e9d80b4baaa2699ed5fc613533a6a147e188.diff

LOG: [llvm][Support] Use ::closesocket for native sockets on Windows (#226613)

Calling ::close on a Windows SOCKET that has not been converted with
_open_osfhandle crashes and aborts the process with 0xC0000409 instead
of returning an error.

Use ::closesocket on Windows for those sockets, and keep ::close on
POSIX.

Added: 
    

Modified: 
    llvm/lib/Support/raw_socket_stream.cpp
    llvm/unittests/Support/raw_socket_stream_test.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Support/raw_socket_stream.cpp b/llvm/lib/Support/raw_socket_stream.cpp
index cdf793c8958f9..50fc680a9538b 100644
--- a/llvm/lib/Support/raw_socket_stream.cpp
+++ b/llvm/lib/Support/raw_socket_stream.cpp
@@ -61,6 +61,21 @@ static std::error_code getLastSocketErrorCode() {
 #endif
 }
 
+#ifdef _WIN32
+using NativeSocket = SOCKET;
+#else
+using NativeSocket = int;
+#define INVALID_SOCKET -1
+#endif
+
+static int closeSocket(NativeSocket Socket) {
+#ifdef _WIN32
+  return ::closesocket(Socket);
+#else
+  return ::close(Socket);
+#endif
+}
+
 static Expected<sockaddr_un> setSocketAddr(StringRef SocketPath) {
   struct sockaddr_un Addr;
   memset(&Addr, 0, sizeof(Addr));
@@ -76,13 +91,8 @@ static Expected<sockaddr_un> setSocketAddr(StringRef SocketPath) {
 }
 
 static Expected<int> 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<StringError>(getLastSocketErrorCode(),
                                          "Create socket failed");
   }
@@ -97,13 +107,16 @@ static Expected<int> getSocketFD(StringRef SocketPath) {
   setsockopt(Socket, SOL_SOCKET, SO_PEERCRED, NULL, 0);
 #endif
   Expected<struct sockaddr_un> 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<StringError>(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<StringError>(EC, "Connect socket failed");
   }
 
 #ifdef _WIN32
@@ -158,12 +171,9 @@ Expected<ListeningSocket> ListeningSocket::createUnix(StringRef SocketPath,
 
 #ifdef _WIN32
   WSABalancer _;
-  SOCKET Socket = socket(AF_UNIX, SOCK_STREAM, 0);
-  if (Socket == INVALID_SOCKET)
-#else
-  int Socket = socket(AF_UNIX, SOCK_STREAM, 0);
-  if (Socket == -1)
 #endif
+  NativeSocket Socket = socket(AF_UNIX, SOCK_STREAM, 0);
+  if (Socket == INVALID_SOCKET)
     return llvm::make_error<StringError>(getLastSocketErrorCode(),
                                          "socket create failed");
 
@@ -177,13 +187,15 @@ Expected<ListeningSocket> ListeningSocket::createUnix(StringRef SocketPath,
   setsockopt(Socket, SOL_SOCKET, SO_PEERCRED, NULL, 0);
 #endif
   Expected<struct sockaddr_un> 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<StringError>(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<std::unique_ptr<raw_socket_stream>> 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


        


More information about the llvm-commits mailing list