[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