Skip to content

Commit 68c0117

Browse files
committed
fix: fio_sock_dup portability + diagnostics
- Windows: add WSA_FLAG_OVERLAPPED to WSASocket call in fio_sock_dup (required for non-blocking IO with WSAPoll/wepoll; was silently missing) - POSIX: replace bare dup() macro with inline function that sets FD_CLOEXEC (prevents listening socket fd leaking into child processes) - Both platforms: add FIO_LOG_ERROR messages on each failure path (WSADuplicateSocket, WSASocket, dup, fcntl each report OS error) - 004 sock.h: fix setsockopt cast (void*) -> (const char*) in fio_sock_open_local for Windows compatibility - 404 ipc.h: fix int fd -> fio_socket_i (2 sites) and fd == -1 -> FIO_SOCK_FD_ISVALID (2 sites) for correct 64-bit Windows socket handles
1 parent b5385c9 commit 68c0117

File tree

3 files changed

+66
-22
lines changed

3 files changed

+66
-22
lines changed

fio-stl.h

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16732,14 +16732,20 @@ FIO_IFUNC fio_socket_i fio_sock_accept(fio_socket_i s,
1673216732
/** Acts as POSIX dup. Use this for portability with WinSock2. */
1673316733
FIO_IFUNC fio_socket_i fio_sock_dup(fio_socket_i original) {
1673416734
WSAPROTOCOL_INFO info;
16735-
if (WSADuplicateSocket((SOCKET)original, GetCurrentProcessId(), &info))
16735+
if (WSADuplicateSocket((SOCKET)original, GetCurrentProcessId(), &info)) {
16736+
FIO_LOG_ERROR("(fio_sock_dup) WSADuplicateSocket failed (WSA error %d)",
16737+
WSAGetLastError());
1673616738
return FIO_SOCKET_INVALID;
16739+
}
1673716740
fio_socket_i fd = (fio_socket_i)WSASocket(FROM_PROTOCOL_INFO,
1673816741
FROM_PROTOCOL_INFO,
1673916742
FROM_PROTOCOL_INFO,
1674016743
&info,
1674116744
0,
16742-
0);
16745+
WSA_FLAG_OVERLAPPED);
16746+
if (!FIO_SOCK_FD_ISVALID(fd))
16747+
FIO_LOG_ERROR("(fio_sock_dup) WSASocket failed (WSA error %d)",
16748+
WSAGetLastError());
1674316749
return fd;
1674416750
}
1674516751
/** Creates a connected socket pair via loopback TCP (Windows socketpair). */
@@ -16808,8 +16814,19 @@ typedef int fio_socket_i;
1680816814
#define fio_sock_write(fd, data, len) write((fd), (data), (len))
1680916815
/** Acts as POSIX read. Use this macro for portability with WinSock2. */
1681016816
#define fio_sock_read(fd, buf, len) read((fd), (buf), (len))
16811-
/** Acts as POSIX dup. Use this macro for portability with WinSock2. */
16812-
#define fio_sock_dup(fd) dup(fd)
16817+
/** Acts as POSIX dup. Sets O_CLOEXEC on the new fd. */
16818+
FIO_IFUNC fio_socket_i fio_sock_dup(fio_socket_i fd) {
16819+
fio_socket_i r = dup(fd);
16820+
if (r == -1) {
16821+
FIO_LOG_ERROR("(fio_sock_dup) dup(%d) failed: %s", fd, strerror(errno));
16822+
return FIO_SOCKET_INVALID;
16823+
}
16824+
if (fcntl(r, F_SETFD, FD_CLOEXEC) == -1)
16825+
FIO_LOG_ERROR("(fio_sock_dup) fcntl(FD_CLOEXEC) failed on fd %d: %s",
16826+
r,
16827+
strerror(errno));
16828+
return r;
16829+
}
1681316830
/** Acts as POSIX close. Use this macro for portability with WinSock2. */
1681416831
#define fio_sock_close(fd) close(fd)
1681516832
/** Acts as POSIX accept. Use this macro for portability with WinSock2. */
@@ -17203,7 +17220,11 @@ SFUNC fio_socket_i fio_sock_open_local(struct addrinfo *addr, int nonblock) {
1720317220
}
1720417221
{ // avoid the "address taken"
1720517222
int optval = 1;
17206-
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(optval));
17223+
setsockopt(fd,
17224+
SOL_SOCKET,
17225+
SO_REUSEADDR,
17226+
(const char *)&optval,
17227+
sizeof(optval));
1720717228
}
1720817229
if (nonblock && fio_sock_set_non_block(fd) == -1) {
1720917230
FIO_LOG_DEBUG("Couldn't set socket to non-blocking mode %s",
@@ -95887,7 +95908,7 @@ FIO_SFUNC void fio___ipc_connect_on_failed(fio_io_protocol_s *protocol,
9588795908
}
9588895909

9588995910
static void fio___ipc_listen_on_data(fio_io_s *io) {
95890-
int fd;
95911+
fio_socket_i fd;
9589195912
fio_io_protocol_s *protocol = (fio_io_protocol_s *)fio_io_udata(io);
9589295913
while (FIO_SOCK_FD_ISVALID(fd = fio_sock_accept(fio_io_fd(io), NULL, NULL))) {
9589395914
FIO_LOG_DDEBUG2("(%d) accepted new IPC connection with fd %d",
@@ -95914,10 +95935,11 @@ FIO_SFUNC void fio___ipc_listen(void *ignr_) {
9591495935
FIO___IPC.ipc_url);
9591595936
}
9591695937

95917-
int fd = fio_sock_open2(FIO___IPC.ipc_url,
95918-
FIO_SOCK_SERVER | FIO_SOCK_TCP | FIO_SOCK_NONBLOCK);
95938+
fio_socket_i fd =
95939+
fio_sock_open2(FIO___IPC.ipc_url,
95940+
FIO_SOCK_SERVER | FIO_SOCK_TCP | FIO_SOCK_NONBLOCK);
9591995941

95920-
FIO_ASSERT(fd != -1,
95942+
FIO_ASSERT(FIO_SOCK_FD_ISVALID(fd),
9592195943
"(%d) failed to start IPC listening @ %s",
9592295944
fio_io_pid(),
9592395945
FIO___IPC.ipc_url);
@@ -96141,11 +96163,11 @@ FIO_SFUNC void fio___ipc_cluster_udp_start(uint16_t port) {
9614196163
/* Open UDP socket */
9614296164
FIO_STR_INFO_TMP_VAR(port_str, 16);
9614396165
fio_string_write_u(&port_str, NULL, (uint64_t)port);
96144-
int fd_udp =
96166+
fio_socket_i fd_udp =
9614596167
fio_sock_open(NULL,
9614696168
port_str.buf,
9614796169
FIO_SOCK_UDP | FIO_SOCK_NONBLOCK | FIO_SOCK_SERVER);
96148-
if (fd_udp == -1) {
96170+
if (!FIO_SOCK_FD_ISVALID(fd_udp)) {
9614996171
FIO_LOG_ERROR("(%d) IPC/RPC couldn't open UDP discovery socket on port %u",
9615096172
fio_io_pid(),
9615196173
(unsigned)port);

fio-stl/004 sock.h

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,20 @@ FIO_IFUNC fio_socket_i fio_sock_accept(fio_socket_i s,
5757
/** Acts as POSIX dup. Use this for portability with WinSock2. */
5858
FIO_IFUNC fio_socket_i fio_sock_dup(fio_socket_i original) {
5959
WSAPROTOCOL_INFO info;
60-
if (WSADuplicateSocket((SOCKET)original, GetCurrentProcessId(), &info))
60+
if (WSADuplicateSocket((SOCKET)original, GetCurrentProcessId(), &info)) {
61+
FIO_LOG_ERROR("(fio_sock_dup) WSADuplicateSocket failed (WSA error %d)",
62+
WSAGetLastError());
6163
return FIO_SOCKET_INVALID;
64+
}
6265
fio_socket_i fd = (fio_socket_i)WSASocket(FROM_PROTOCOL_INFO,
6366
FROM_PROTOCOL_INFO,
6467
FROM_PROTOCOL_INFO,
6568
&info,
6669
0,
67-
0);
70+
WSA_FLAG_OVERLAPPED);
71+
if (!FIO_SOCK_FD_ISVALID(fd))
72+
FIO_LOG_ERROR("(fio_sock_dup) WSASocket failed (WSA error %d)",
73+
WSAGetLastError());
6874
return fd;
6975
}
7076
/** Creates a connected socket pair via loopback TCP (Windows socketpair). */
@@ -133,8 +139,19 @@ typedef int fio_socket_i;
133139
#define fio_sock_write(fd, data, len) write((fd), (data), (len))
134140
/** Acts as POSIX read. Use this macro for portability with WinSock2. */
135141
#define fio_sock_read(fd, buf, len) read((fd), (buf), (len))
136-
/** Acts as POSIX dup. Use this macro for portability with WinSock2. */
137-
#define fio_sock_dup(fd) dup(fd)
142+
/** Acts as POSIX dup. Sets O_CLOEXEC on the new fd. */
143+
FIO_IFUNC fio_socket_i fio_sock_dup(fio_socket_i fd) {
144+
fio_socket_i r = dup(fd);
145+
if (r == -1) {
146+
FIO_LOG_ERROR("(fio_sock_dup) dup(%d) failed: %s", fd, strerror(errno));
147+
return FIO_SOCKET_INVALID;
148+
}
149+
if (fcntl(r, F_SETFD, FD_CLOEXEC) == -1)
150+
FIO_LOG_ERROR("(fio_sock_dup) fcntl(FD_CLOEXEC) failed on fd %d: %s",
151+
r,
152+
strerror(errno));
153+
return r;
154+
}
138155
/** Acts as POSIX close. Use this macro for portability with WinSock2. */
139156
#define fio_sock_close(fd) close(fd)
140157
/** Acts as POSIX accept. Use this macro for portability with WinSock2. */
@@ -528,7 +545,11 @@ SFUNC fio_socket_i fio_sock_open_local(struct addrinfo *addr, int nonblock) {
528545
}
529546
{ // avoid the "address taken"
530547
int optval = 1;
531-
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(optval));
548+
setsockopt(fd,
549+
SOL_SOCKET,
550+
SO_REUSEADDR,
551+
(const char *)&optval,
552+
sizeof(optval));
532553
}
533554
if (nonblock && fio_sock_set_non_block(fd) == -1) {
534555
FIO_LOG_DEBUG("Couldn't set socket to non-blocking mode %s",

fio-stl/404 ipc.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,7 +1331,7 @@ FIO_SFUNC void fio___ipc_connect_on_failed(fio_io_protocol_s *protocol,
13311331
}
13321332

13331333
static void fio___ipc_listen_on_data(fio_io_s *io) {
1334-
int fd;
1334+
fio_socket_i fd;
13351335
fio_io_protocol_s *protocol = (fio_io_protocol_s *)fio_io_udata(io);
13361336
while (FIO_SOCK_FD_ISVALID(fd = fio_sock_accept(fio_io_fd(io), NULL, NULL))) {
13371337
FIO_LOG_DDEBUG2("(%d) accepted new IPC connection with fd %d",
@@ -1358,10 +1358,11 @@ FIO_SFUNC void fio___ipc_listen(void *ignr_) {
13581358
FIO___IPC.ipc_url);
13591359
}
13601360

1361-
int fd = fio_sock_open2(FIO___IPC.ipc_url,
1362-
FIO_SOCK_SERVER | FIO_SOCK_TCP | FIO_SOCK_NONBLOCK);
1361+
fio_socket_i fd =
1362+
fio_sock_open2(FIO___IPC.ipc_url,
1363+
FIO_SOCK_SERVER | FIO_SOCK_TCP | FIO_SOCK_NONBLOCK);
13631364

1364-
FIO_ASSERT(fd != -1,
1365+
FIO_ASSERT(FIO_SOCK_FD_ISVALID(fd),
13651366
"(%d) failed to start IPC listening @ %s",
13661367
fio_io_pid(),
13671368
FIO___IPC.ipc_url);
@@ -1585,11 +1586,11 @@ FIO_SFUNC void fio___ipc_cluster_udp_start(uint16_t port) {
15851586
/* Open UDP socket */
15861587
FIO_STR_INFO_TMP_VAR(port_str, 16);
15871588
fio_string_write_u(&port_str, NULL, (uint64_t)port);
1588-
int fd_udp =
1589+
fio_socket_i fd_udp =
15891590
fio_sock_open(NULL,
15901591
port_str.buf,
15911592
FIO_SOCK_UDP | FIO_SOCK_NONBLOCK | FIO_SOCK_SERVER);
1592-
if (fd_udp == -1) {
1593+
if (!FIO_SOCK_FD_ISVALID(fd_udp)) {
15931594
FIO_LOG_ERROR("(%d) IPC/RPC couldn't open UDP discovery socket on port %u",
15941595
fio_io_pid(),
15951596
(unsigned)port);

0 commit comments

Comments
 (0)