From 97929ed4962aa4f6b7e0c1cf3e48a65292aea77b Mon Sep 17 00:00:00 2001 From: Severin Leonhardt Date: Wed, 14 Jun 2023 11:14:58 +0200 Subject: [PATCH] Fix building ExportedConnection on Windows The `` header isn't available on Windows. The `dup` function is deprecated[^1] and apparently also not the correct function here. On Windows `uv_fileno` currently returns a `SOCKET`[^2] cast into `uv_os_fd_t`[^3]. Contrary to many other handles this handle type can't be duplicated using `DuplicateHandle`[^4]. `WSADuplicateSocket` has to be used instead. As documented an actual `SOCKET` has to be constructed from `WSAPROTOCOL_INFOW`. The parameters are taken from the struct, except for `g` and `dwFlags` which were taken from libuv's implementation[^5]. Error handling was omitted like with `uv_fileno` and `dup` already. Also changed the type of `fd` to what `uv_tcp_open` expects which is `SOCKET` instead of `int` on Windows. [^1]: https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/posix-dup-dup2 [^2]: https://github.com/libuv/libuv/blob/2f1614b1286f53b3b2ab96a15a525cb25462ba9a/include/uv/win.h#L456 [^3]: https://github.com/libuv/libuv/blob/2f1614b1286f53b3b2ab96a15a525cb25462ba9a/src/win/core.c#L689 [^4]: https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-duplicatehandle#remarks [^5]: https://github.com/libuv/libuv/blob/2f1614b1286f53b3b2ab96a15a525cb25462ba9a/src/win/tcp.c#L1281-L1282 --- src/exported_connection.cpp | 9 +++++++++ src/exported_connection.hpp | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/exported_connection.cpp b/src/exported_connection.cpp index 2d0fdc920..06af7fcd2 100644 --- a/src/exported_connection.cpp +++ b/src/exported_connection.cpp @@ -1,4 +1,6 @@ +#if !defined(_WIN32) #include +#endif #include "exported_connection.hpp" #include "connection.hpp" @@ -20,8 +22,15 @@ ExportedConnection::ExportedConnection(SharedRefPtr connection) { this->heartbeat_interval_secs_ = connection->heartbeat_interval_secs_; // Socket +#if defined(_WIN32) + uv_fileno(reinterpret_cast(&connection->socket_->tcp_), reinterpret_cast(&this->fd)); + WSAPROTOCOL_INFOW info; + WSADuplicateSocketW(this->fd, GetCurrentProcessId(), &info); + this->fd = WSASocketW(info.iAddressFamily, info.iSocketType, info.iProtocol, &info, 0, WSA_FLAG_OVERLAPPED); +#else uv_fileno(reinterpret_cast(&connection->socket_->tcp_), &this->fd); this->fd = dup(this->fd); +#endif this->handler_ = connection->socket_->handler_.release(); // Set basic handler, to notify Connection about closing, and destroy it. connection->socket_->set_handler(new ConnectionHandler(connection.get())); diff --git a/src/exported_connection.hpp b/src/exported_connection.hpp index d5a76ec55..040187f21 100644 --- a/src/exported_connection.hpp +++ b/src/exported_connection.hpp @@ -40,7 +40,7 @@ class ExportedConnection : public RefCounted { unsigned int heartbeat_interval_secs_; // Socket fields - int fd; + uv_os_sock_t fd; SocketHandlerBase *handler_; bool is_defunct_; size_t max_reusable_write_objects_;