src: change code according to review.

This commit is contained in:
reito 2026-02-06 22:56:44 +08:00
parent 1ae7779e1c
commit 08d605e3db
4 changed files with 77 additions and 65 deletions

View File

@ -52,6 +52,10 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
int uv_pipe_init_ex(uv_loop_t* loop, uv_pipe_t* handle, unsigned int flags) {
int ipc = (flags & UV_PIPE_INIT_IPC) != 0;
if (flags & ~(UV_PIPE_INIT_IPC | UV_PIPE_INIT_WIN_UDS))
return UV_EINVAL;
if (flags & UV_PIPE_INIT_WIN_UDS)
return UV_EINVAL;
uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);
handle->shutdown_req = NULL;

View File

@ -35,9 +35,13 @@
#include <aclapi.h>
#include <accctrl.h>
/* Runtime feature check: prefer if (UV__ENABLE_WIN_UDS_PIPE) over #ifdef
* so the compiler checks both code paths even when not enabled. */
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__MINGW64__)
#define UV__ENABLE_WIN_UDS_PIPE
#include <afunix.h>
#define UV__ENABLE_WIN_UDS_PIPE 1
#else
#define UV__ENABLE_WIN_UDS_PIPE 0
#endif
/* A zero-size buffer for use by uv_pipe_read */
@ -126,7 +130,7 @@ static int uv__win_uds_pipe_file_exists(const char* path, int* exists) {
*exists = (attrib != INVALID_FILE_ATTRIBUTES &&
!(attrib & FILE_ATTRIBUTE_DIRECTORY));
free(wpath);
uv__free(wpath);
return 0;
}
@ -169,6 +173,10 @@ int uv_pipe_init_ex(uv_loop_t* loop, uv_pipe_t* handle, unsigned int flags) {
int ipc = (flags & UV_PIPE_INIT_IPC) != 0;
int uds = (flags & UV_PIPE_INIT_WIN_UDS) != 0;
/* Reject unknown flags for forwards compatibility. */
if (flags & ~(UV_PIPE_INIT_IPC | UV_PIPE_INIT_WIN_UDS))
return UV_EINVAL;
if (ipc && uds) {
/* Unix domain socket on Windows doesn't work with IPC mode currently. */
return EINVAL;
@ -614,7 +622,7 @@ uds_pipe:
}
#if defined(UV__ENABLE_WIN_UDS_PIPE)
#if UV__ENABLE_WIN_UDS_PIPE
static int pipe_alloc_accept_unix_domain_socket(uv_loop_t* loop, uv_pipe_t* handle,
uv_pipe_accept_t* req, const char* name, BOOL firstInstance) {
int ret = 0, err = 0;
@ -639,7 +647,7 @@ static int pipe_alloc_accept_unix_domain_socket(uv_loop_t* loop, uv_pipe_t* hand
}
addr.sun_family = AF_UNIX;
ret = uv__strscpy(addr.sun_path, name, UNIX_PATH_MAX);
ret = uv__strscpy(addr.sun_path, name, sizeof(addr.sun_path));
if (ret < 0) {
return ret;
}
@ -656,6 +664,7 @@ static int pipe_alloc_accept_unix_domain_socket(uv_loop_t* loop, uv_pipe_t* hand
loop->iocp,
(ULONG_PTR) handle,
0) == NULL) {
closesocket(server_fd);
return GetLastError();
}
@ -877,23 +886,19 @@ int uv_pipe_bind2(uv_pipe_t* handle,
use_uds_pipe = (handle->flags & UV_HANDLE_WIN_UDS_PIPE) != 0;
#if !defined(UV__ENABLE_WIN_UDS_PIPE)
#if UV__ENABLE_WIN_UDS_PIPE
/* Since UDS on Windows is a new feature, always reject too-long paths
* (no truncation for backwards compatibility needed). */
if (use_uds_pipe) {
if (namelen >= sizeof(((struct sockaddr_un*) 0)->sun_path))
return UV_EINVAL;
}
#else
if (use_uds_pipe) {
return UV_ENOSYS;
}
#endif
#if defined(UV__ENABLE_WIN_UDS_PIPE)
if (use_uds_pipe) {
if (flags & UV_PIPE_NO_TRUNCATE)
if (namelen >= UNIX_PATH_MAX)
return UV_EINVAL;
if (namelen >= UNIX_PATH_MAX)
namelen = UNIX_PATH_MAX - 1;
}
#endif
/* Already bound? */
if (handle->flags & UV_HANDLE_BOUND) {
return UV_EINVAL;
@ -937,22 +942,22 @@ int uv_pipe_bind2(uv_pipe_t* handle,
req->next_pending = NULL;
}
if (!use_uds_pipe) {
if (use_uds_pipe) {
/* Use unix domain socket we save the original path name copy. */
handle->pathname = name_copy;
name_copy = NULL;
} else {
/* TODO(bnoordhuis) Add converters that take a |length| parameter. */
err = uv__convert_utf8_to_utf16(name_copy, &handle->name);
uv__free(name_copy);
name_copy = NULL;
} else {
/* Use unix domain socket we save the original path name copy. */
handle->pathname = name_copy;
name_copy = NULL;
}
if (err) {
goto error;
}
#if defined(UV__ENABLE_WIN_UDS_PIPE)
#if UV__ENABLE_WIN_UDS_PIPE
if (use_uds_pipe) {
err = uv__win_uds_pipe_file_exists(handle->pathname, &uds_file_exists);
if (err) {
@ -1095,10 +1100,11 @@ int uv_pipe_connect2(uv_connect_t* req,
HANDLE pipeHandle = INVALID_HANDLE_VALUE;
DWORD duplex_flags;
char* name_copy;
DWORD bytes;
int use_uds_pipe;
#if defined(UV__ENABLE_WIN_UDS_PIPE)
#if UV__ENABLE_WIN_UDS_PIPE
int uds_file_exists;
SOCKET uds_client_fd;
struct sockaddr_un uds_addr_bind = {0};
@ -1131,25 +1137,19 @@ int uv_pipe_connect2(uv_connect_t* req,
use_uds_pipe = (handle->flags & UV_HANDLE_WIN_UDS_PIPE) != 0;
#if !defined(UV__ENABLE_WIN_UDS_PIPE)
#if UV__ENABLE_WIN_UDS_PIPE
/* Since UDS on Windows is a new feature, always reject too-long paths
* (no truncation for backwards compatibility needed). */
if (use_uds_pipe) {
if (namelen >= sizeof(((struct sockaddr_un*) 0)->sun_path))
return UV_EINVAL;
}
#else
if (use_uds_pipe) {
return UV_ENOSYS;
}
#endif
#if defined(UV__ENABLE_WIN_UDS_PIPE)
if (use_uds_pipe) {
/* https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ */
/* a null-terminated UTF-8 file system path */
if (flags & UV_PIPE_NO_TRUNCATE)
if (namelen >= UNIX_PATH_MAX)
return UV_EINVAL;
if (namelen >= UNIX_PATH_MAX)
namelen = UNIX_PATH_MAX - 1;
}
#endif
name_copy = uv__malloc(namelen + 1);
if (name_copy == NULL) {
return UV_ENOMEM;
@ -1168,15 +1168,15 @@ int uv_pipe_connect2(uv_connect_t* req,
}
uv__pipe_connection_init(handle);
if (!use_uds_pipe) {
if (use_uds_pipe) {
/* Use unix domain socket we save the original path name copy. */
handle->pathname = name_copy;
name_copy = NULL;
} else {
/* TODO(bnoordhuis) Add converters that take a |length| parameter. */
err = uv__convert_utf8_to_utf16(name_copy, &handle->name);
uv__free(name_copy);
name_copy = NULL;
} else {
/* Use unix domain socket we save the original path name copy. */
handle->pathname = name_copy;
name_copy = NULL;
}
if (err) {
@ -1184,7 +1184,7 @@ int uv_pipe_connect2(uv_connect_t* req,
goto error;
}
#if defined(UV__ENABLE_WIN_UDS_PIPE)
#if UV__ENABLE_WIN_UDS_PIPE
if (use_uds_pipe) {
err = uv__win_uds_pipe_file_exists(handle->pathname, &uds_file_exists);
if (err) {
@ -1206,7 +1206,9 @@ int uv_pipe_connect2(uv_connect_t* req,
uds_addr_bind.sun_family = AF_UNIX;
/* ConnectEx need to be initially bound */
int ret = bind(uds_client_fd, (const struct sockaddr*)&uds_addr_bind, sizeof(uds_addr_bind));
int ret = bind(uds_client_fd,
(const struct sockaddr*) &uds_addr_bind,
sizeof(uds_addr_bind));
if (ret != 0) {
err = WSAGetLastError();
closesocket(uds_client_fd);
@ -1232,10 +1234,10 @@ int uv_pipe_connect2(uv_connect_t* req,
ret = uv_wsa_connectex(uds_client_fd,
(const struct sockaddr*) &uds_addr_real,
sizeof(struct sockaddr_un),
sizeof(uds_addr_real),
NULL,
0,
NULL,
&bytes,
&req->u.io.overlapped);
if (!ret) {
@ -1446,7 +1448,7 @@ static void uv__pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
assert(handle->flags & UV_HANDLE_LISTENING);
if (!firstInstance) {
#if defined(UV__ENABLE_WIN_UDS_PIPE)
#if UV__ENABLE_WIN_UDS_PIPE
if (handle->flags & UV_HANDLE_WIN_UDS_PIPE) {
uds_err = pipe_alloc_accept_unix_domain_socket(
loop, handle, req, handle->pathname, FALSE);
@ -1476,6 +1478,10 @@ uds_pipe:
memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
if (handle->flags & UV_HANDLE_WIN_UDS_PIPE) {
/* AcceptEx requires dwLocalAddressLength and dwRemoteAddressLength to be
* at least 16 bytes more than the maximum address length for the transport
* protocol in use. See MSDN AcceptEx documentation.
* https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-acceptex */
if (!uv_wsa_acceptex((SOCKET)handle->handle,
(SOCKET)req->pipeHandle,
req->accept_buffer,

View File

@ -35,8 +35,8 @@ struct sockaddr_in uv_addr_ip4_any_;
struct sockaddr_in6 uv_addr_ip6_any_;
/* WSA function pointers */
LPFN_ACCEPTEX uv_wsa_acceptex = NULL;
LPFN_CONNECTEX uv_wsa_connectex = NULL;
LPFN_ACCEPTEX uv_wsa_acceptex;
LPFN_CONNECTEX uv_wsa_connectex;
/*

View File

@ -28,17 +28,17 @@
#define UV_SUPPORTS_WIN_UDS
#endif
static int use_shutdown = 0;
static int use_shutdown;
static uv_shutdown_t shutdown_client;
static int close_cb_called = 0;
static int shutdown_cb_called = 0;
static int server_connect_cb_called = 0;
static int client_connect_cb_called = 0;
static int close_cb_called;
static int shutdown_cb_called;
static int server_connect_cb_called;
static int client_connect_cb_called;
static uv_pipe_t pipe_server;
static uv_pipe_t pipe_client;
const char pipe_test_data[] = "send test through win uds pipe";
static const char pipe_test_data[] = "send test through win uds pipe";
static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
@ -116,7 +116,9 @@ static void server_connect_cb(uv_stream_t* handle, int status) {
int test_pipe_win_uds() {
#if defined(UV_SUPPORTS_WIN_UDS)
#ifndef UV_SUPPORTS_WIN_UDS
RETURN_SKIP("Windows-only test");
#endif
int r;
uv_fs_t fs;
uv_connect_t req;
@ -157,7 +159,6 @@ int test_pipe_win_uds() {
ASSERT_EQ(2, close_cb_called);
ASSERT_EQ(1, server_connect_cb_called);
ASSERT_EQ(1, client_connect_cb_called);
#endif
MAKE_VALGRIND_HAPPY(uv_default_loop());
return 0;
@ -182,7 +183,9 @@ static void bad_name_connect_cb(uv_connect_t* connect_req, int status) {
TEST_IMPL(pipe_win_uds_bad_name) {
#if defined(UV_SUPPORTS_WIN_UDS)
#ifndef UV_SUPPORTS_WIN_UDS
RETURN_SKIP("Windows-only test");
#endif
int r;
uv_connect_t req;
uv_pipe_t pipe_server_1;
@ -210,7 +213,6 @@ TEST_IMPL(pipe_win_uds_bad_name) {
// Run the loop
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
#endif
MAKE_VALGRIND_HAPPY(uv_default_loop());
return 0;