aboutsummaryrefslogtreecommitdiff
path: root/lib/std/net.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2025-08-10 11:06:36 -0700
committerGitHub <noreply@github.com>2025-08-10 11:06:36 -0700
commite25168d01be35bea2c8e811fb5fddab847ae6938 (patch)
tree2b085034a0cd8e46fb778dea134d48e55e7be418 /lib/std/net.zig
parent6eeceb4b14965a11d3f6b2969b82a696ba99bffc (diff)
parent95f57c3369181123aa7ebd4a9654fc489f8bb4fd (diff)
downloadzig-e25168d01be35bea2c8e811fb5fddab847ae6938.tar.gz
zig-e25168d01be35bea2c8e811fb5fddab847ae6938.zip
Merge pull request #24774 from kcbanner/fixup_webui_windows
Fix `respondWebSocket`, use overlapped sockets on Windows, and re-enable --webui
Diffstat (limited to 'lib/std/net.zig')
-rw-r--r--lib/std/net.zig74
1 files changed, 63 insertions, 11 deletions
diff --git a/lib/std/net.zig b/lib/std/net.zig
index f63aa6dd0a..45abc42568 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -259,6 +259,7 @@ pub const Address = extern union {
/// Sets SO_REUSEADDR and SO_REUSEPORT on POSIX.
/// Sets SO_REUSEADDR on Windows, which is roughly equivalent.
reuse_address: bool = false,
+ /// Sets O_NONBLOCK.
force_nonblocking: bool = false,
};
@@ -1998,11 +1999,8 @@ pub const Stream = struct {
return n;
}
- fn streamBufs(r: *Reader, bufs: []windows.ws2_32.WSABUF) Error!u32 {
- var n: u32 = undefined;
- var flags: u32 = 0;
- const rc = windows.ws2_32.WSARecvFrom(r.net_stream.handle, bufs.ptr, @intCast(bufs.len), &n, &flags, null, null, null, null);
- if (rc != 0) switch (windows.ws2_32.WSAGetLastError()) {
+ fn handleRecvError(winsock_error: windows.ws2_32.WinsockError) Error!void {
+ switch (winsock_error) {
.WSAECONNRESET => return error.ConnectionResetByPeer,
.WSAEFAULT => unreachable, // a pointer is not completely contained in user address space.
.WSAEINPROGRESS, .WSAEINTR => unreachable, // deprecated and removed in WSA 2.2
@@ -2013,10 +2011,39 @@ pub const Stream = struct {
.WSAENOTCONN => return error.SocketNotConnected,
.WSAEWOULDBLOCK => return error.WouldBlock,
.WSANOTINITIALISED => unreachable, // WSAStartup must be called before this function
- .WSA_IO_PENDING => unreachable, // not using overlapped I/O
+ .WSA_IO_PENDING => unreachable,
.WSA_OPERATION_ABORTED => unreachable, // not using overlapped I/O
else => |err| return windows.unexpectedWSAError(err),
+ }
+ }
+
+ fn streamBufs(r: *Reader, bufs: []windows.ws2_32.WSABUF) Error!u32 {
+ var flags: u32 = 0;
+ var overlapped: windows.OVERLAPPED = std.mem.zeroes(windows.OVERLAPPED);
+
+ var n: u32 = undefined;
+ if (windows.ws2_32.WSARecv(
+ r.net_stream.handle,
+ bufs.ptr,
+ @intCast(bufs.len),
+ &n,
+ &flags,
+ &overlapped,
+ null,
+ ) == windows.ws2_32.SOCKET_ERROR) switch (windows.ws2_32.WSAGetLastError()) {
+ .WSA_IO_PENDING => {
+ var result_flags: u32 = undefined;
+ if (windows.ws2_32.WSAGetOverlappedResult(
+ r.net_stream.handle,
+ &overlapped,
+ &n,
+ windows.TRUE,
+ &result_flags,
+ ) == windows.FALSE) try handleRecvError(windows.ws2_32.WSAGetLastError());
+ },
+ else => |winsock_error| try handleRecvError(winsock_error),
};
+
return n;
}
},
@@ -2136,10 +2163,8 @@ pub const Stream = struct {
return io_w.consume(n);
}
- fn sendBufs(handle: Stream.Handle, bufs: []windows.ws2_32.WSABUF) Error!u32 {
- var n: u32 = undefined;
- const rc = windows.ws2_32.WSASend(handle, bufs.ptr, @intCast(bufs.len), &n, 0, null, null);
- if (rc == windows.ws2_32.SOCKET_ERROR) switch (windows.ws2_32.WSAGetLastError()) {
+ fn handleSendError(winsock_error: windows.ws2_32.WinsockError) Error!void {
+ switch (winsock_error) {
.WSAECONNABORTED => return error.ConnectionResetByPeer,
.WSAECONNRESET => return error.ConnectionResetByPeer,
.WSAEFAULT => unreachable, // a pointer is not completely contained in user address space.
@@ -2155,10 +2180,37 @@ pub const Stream = struct {
.WSAESHUTDOWN => unreachable, // cannot send on a socket after write shutdown
.WSAEWOULDBLOCK => return error.WouldBlock,
.WSANOTINITIALISED => unreachable, // WSAStartup must be called before this function
- .WSA_IO_PENDING => unreachable, // not using overlapped I/O
+ .WSA_IO_PENDING => unreachable,
.WSA_OPERATION_ABORTED => unreachable, // not using overlapped I/O
else => |err| return windows.unexpectedWSAError(err),
+ }
+ }
+
+ fn sendBufs(handle: Stream.Handle, bufs: []windows.ws2_32.WSABUF) Error!u32 {
+ var n: u32 = undefined;
+ var overlapped: windows.OVERLAPPED = std.mem.zeroes(windows.OVERLAPPED);
+ if (windows.ws2_32.WSASend(
+ handle,
+ bufs.ptr,
+ @intCast(bufs.len),
+ &n,
+ 0,
+ &overlapped,
+ null,
+ ) == windows.ws2_32.SOCKET_ERROR) switch (windows.ws2_32.WSAGetLastError()) {
+ .WSA_IO_PENDING => {
+ var result_flags: u32 = undefined;
+ if (windows.ws2_32.WSAGetOverlappedResult(
+ handle,
+ &overlapped,
+ &n,
+ windows.TRUE,
+ &result_flags,
+ ) == windows.FALSE) try handleSendError(windows.ws2_32.WSAGetLastError());
+ },
+ else => |winsock_error| try handleSendError(winsock_error),
};
+
return n;
}
},