authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-21 07:10:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:50-07:00
logd257b1337a1b0cbe5b2694518017216aa1d2ef1a
tree11bdf94a0a5a262297d371e7190c83c43dc30c57
parentaadd8d4a3efd8912c47b8ea1bbd4c3a6649c3e5d

std.Io.Threaded: fix compilation failures on Windows


4 files changed, 183 insertions(+), 141 deletions(-)

lib/std/Io/Threaded.zig+172-121
...@@ -220,8 +220,14 @@ pub fn io(t: *Threaded) Io {...@@ -220,8 +220,14 @@ pub fn io(t: *Threaded) Io {
220 .fileClose = fileClose,220 .fileClose = fileClose,
221 .fileWriteStreaming = fileWriteStreaming,221 .fileWriteStreaming = fileWriteStreaming,
222 .fileWritePositional = fileWritePositional,222 .fileWritePositional = fileWritePositional,
223 .fileReadStreaming = fileReadStreaming,223 .fileReadStreaming = switch (builtin.os.tag) {
224 .fileReadPositional = fileReadPositional,224 .windows => fileReadStreamingWindows,
225 else => fileReadStreamingPosix,
226 },
227 .fileReadPositional = switch (builtin.os.tag) {
228 .windows => fileReadPositionalWindows,
229 else => fileReadPositionalPosix,
230 },
225 .fileSeekBy = fileSeekBy,231 .fileSeekBy = fileSeekBy,
226 .fileSeekTo = fileSeekTo,232 .fileSeekTo = fileSeekTo,
227 .openSelfExe = openSelfExe,233 .openSelfExe = openSelfExe,
...@@ -258,15 +264,21 @@ pub fn io(t: *Threaded) Io {...@@ -258,15 +264,21 @@ pub fn io(t: *Threaded) Io {
258 .netConnectUnix = netConnectUnix,264 .netConnectUnix = netConnectUnix,
259 .netClose = netClose,265 .netClose = netClose,
260 .netRead = switch (builtin.os.tag) {266 .netRead = switch (builtin.os.tag) {
261 .windows => @panic("TODO"),267 .windows => netReadWindows,
262 else => netReadPosix,268 else => netReadPosix,
263 },269 },
264 .netWrite = switch (builtin.os.tag) {270 .netWrite = switch (builtin.os.tag) {
265 .windows => @panic("TODO"),271 .windows => netWriteWindows,
266 else => netWritePosix,272 else => netWritePosix,
267 },273 },
268 .netSend = netSend,274 .netSend = switch (builtin.os.tag) {
269 .netReceive = netReceive,275 .windows => netSendWindows,
276 else => netSendPosix,
277 },
278 .netReceive = switch (builtin.os.tag) {
279 .windows => netReceiveWindows,
280 else => netReceivePosix,
281 },
270 .netInterfaceNameResolve = netInterfaceNameResolve,282 .netInterfaceNameResolve = netInterfaceNameResolve,
271 .netInterfaceName = netInterfaceName,283 .netInterfaceName = netInterfaceName,
272 .netLookup = netLookup,284 .netLookup = netLookup,
...@@ -284,6 +296,10 @@ const have_futex = switch (builtin.cpu.arch) {...@@ -284,6 +296,10 @@ const have_futex = switch (builtin.cpu.arch) {
284 .wasm32, .wasm64 => builtin.cpu.has(.wasm, .atomics),296 .wasm32, .wasm64 => builtin.cpu.has(.wasm, .atomics),
285 else => true,297 else => true,
286};298};
299const have_preadv = switch (native_os) {
300 .windows, .haiku, .serenity => false, // 💩💩💩
301 else => true,
302};
287303
288const openat_sym = if (posix.lfs64_abi) posix.system.openat64 else posix.system.openat;304const openat_sym = if (posix.lfs64_abi) posix.system.openat64 else posix.system.openat;
289const fstat_sym = if (posix.lfs64_abi) posix.system.fstat64 else posix.system.fstat;305const fstat_sym = if (posix.lfs64_abi) posix.system.fstat64 else posix.system.fstat;
...@@ -1899,12 +1915,19 @@ fn dirOpenFileWindows(...@@ -1899,12 +1915,19 @@ fn dirOpenFileWindows(
1899 flags: Io.File.OpenFlags,1915 flags: Io.File.OpenFlags,
1900) Io.File.OpenError!Io.File {1916) Io.File.OpenError!Io.File {
1901 const t: *Threaded = @ptrCast(@alignCast(userdata));1917 const t: *Threaded = @ptrCast(@alignCast(userdata));
1902 try t.checkCancel();1918 const sub_path_w_array = try windows.sliceToPrefixedFileW(dir.handle, sub_path);
1903
1904 const w = windows;
1905 const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, sub_path);
1906 const sub_path_w = sub_path_w_array.span();1919 const sub_path_w = sub_path_w_array.span();
1920 return dirOpenFileWindowsInner(t, dir, sub_path_w, flags);
1921}
19071922
1923fn dirOpenFileWindowsInner(
1924 t: *Threaded,
1925 dir: Io.Dir,
1926 sub_path_w: [:0]const u16,
1927 flags: Io.File.OpenFlags,
1928) Io.File.OpenError!Io.File {
1929 try t.checkCancel();
1930 const w = windows;
1908 const handle = try w.OpenFile(sub_path_w, .{1931 const handle = try w.OpenFile(sub_path_w, .{
1909 .dir = dir.handle,1932 .dir = dir.handle,
1910 .access_mask = w.SYNCHRONIZE |1933 .access_mask = w.SYNCHRONIZE |
...@@ -2247,47 +2270,9 @@ fn fileClose(userdata: ?*anyopaque, file: Io.File) void {...@@ -2247,47 +2270,9 @@ fn fileClose(userdata: ?*anyopaque, file: Io.File) void {
2247 posix.close(file.handle);2270 posix.close(file.handle);
2248}2271}
22492272
2250fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File.ReadStreamingError!usize {2273fn fileReadStreamingPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File.ReadStreamingError!usize {
2251 const t: *Threaded = @ptrCast(@alignCast(userdata));2274 const t: *Threaded = @ptrCast(@alignCast(userdata));
22522275
2253 if (is_windows) {
2254 const DWORD = windows.DWORD;
2255 var index: usize = 0;
2256 var truncate: usize = 0;
2257 var total: usize = 0;
2258 while (index < data.len) {
2259 try t.checkCancel();
2260 {
2261 const untruncated = data[index];
2262 data[index] = untruncated[truncate..];
2263 defer data[index] = untruncated;
2264 const buffer = data[index..];
2265 const want_read_count: DWORD = @min(std.math.maxInt(DWORD), buffer.len);
2266 var n: DWORD = undefined;
2267 if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, null) == 0) {
2268 switch (windows.GetLastError()) {
2269 .IO_PENDING => |err| return windows.statusBug(err),
2270 .OPERATION_ABORTED => continue,
2271 .BROKEN_PIPE => return 0,
2272 .HANDLE_EOF => return 0,
2273 .NETNAME_DELETED => return error.ConnectionResetByPeer,
2274 .LOCK_VIOLATION => return error.LockViolation,
2275 .ACCESS_DENIED => return error.AccessDenied,
2276 .INVALID_HANDLE => return error.NotOpenForReading,
2277 else => |err| return windows.unexpectedError(err),
2278 }
2279 }
2280 total += n;
2281 truncate += n;
2282 }
2283 while (index < data.len and truncate >= data[index].len) {
2284 truncate -= data[index].len;
2285 index += 1;
2286 }
2287 }
2288 return total;
2289 }
2290
2291 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;2276 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;
2292 var i: usize = 0;2277 var i: usize = 0;
2293 for (data) |buf| {2278 for (data) |buf| {
...@@ -2348,70 +2333,37 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File...@@ -2348,70 +2333,37 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File
2348 }2333 }
2349}2334}
23502335
2351fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset: u64) Io.File.ReadPositionalError!usize {2336fn fileReadStreamingWindows(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File.ReadStreamingError!usize {
2352 const t: *Threaded = @ptrCast(@alignCast(userdata));2337 const t: *Threaded = @ptrCast(@alignCast(userdata));
2338 try t.checkCancel();
23532339
2354 if (is_windows) {2340 const DWORD = windows.DWORD;
2355 const DWORD = windows.DWORD;2341 var index: usize = 0;
2356 const OVERLAPPED = windows.OVERLAPPED;2342 while (data[index].len == 0) index += 1;
2357 var index: usize = 0;2343
2358 var truncate: usize = 0;2344 const buffer = data[index];
2359 var total: usize = 0;2345 const want_read_count: DWORD = @min(std.math.maxInt(DWORD), buffer.len);
2360 while (true) {2346 var n: DWORD = undefined;
2361 try t.checkCancel();2347 if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, null) == 0) {
2362 {2348 switch (windows.GetLastError()) {
2363 const untruncated = data[index];2349 .IO_PENDING => |err| return windows.errorBug(err),
2364 data[index] = untruncated[truncate..];2350 .OPERATION_ABORTED => return error.Canceled,
2365 defer data[index] = untruncated;2351 .BROKEN_PIPE => return 0,
2366 const buffer = data[index..];2352 .HANDLE_EOF => return 0,
2367 const want_read_count: DWORD = @min(std.math.maxInt(DWORD), buffer.len);2353 .NETNAME_DELETED => return error.ConnectionResetByPeer,
2368 var n: DWORD = undefined;2354 .LOCK_VIOLATION => return error.LockViolation,
2369 var overlapped_data: OVERLAPPED = undefined;2355 .ACCESS_DENIED => return error.AccessDenied,
2370 const overlapped: ?*OVERLAPPED = if (offset) |off| blk: {2356 .INVALID_HANDLE => return error.NotOpenForReading,
2371 overlapped_data = .{2357 else => |err| return windows.unexpectedError(err),
2372 .Internal = 0,
2373 .InternalHigh = 0,
2374 .DUMMYUNIONNAME = .{
2375 .DUMMYSTRUCTNAME = .{
2376 .Offset = @as(u32, @truncate(off)),
2377 .OffsetHigh = @as(u32, @truncate(off >> 32)),
2378 },
2379 },
2380 .hEvent = null,
2381 };
2382 break :blk &overlapped_data;
2383 } else null;
2384 if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, overlapped) == 0) {
2385 switch (windows.GetLastError()) {
2386 .IO_PENDING => |err| return windows.statusBug(err),
2387 .OPERATION_ABORTED => continue,
2388 .BROKEN_PIPE => return 0,
2389 .HANDLE_EOF => return 0,
2390 .NETNAME_DELETED => return error.ConnectionResetByPeer,
2391 .LOCK_VIOLATION => return error.LockViolation,
2392 .ACCESS_DENIED => return error.AccessDenied,
2393 .INVALID_HANDLE => return error.NotOpenForReading,
2394 else => |err| return windows.unexpectedError(err),
2395 }
2396 }
2397 total += n;
2398 truncate += n;
2399 }
2400 while (index < data.len and truncate >= data[index].len) {
2401 truncate -= data[index].len;
2402 index += 1;
2403 }
2404 }2358 }
2405 return total;
2406 }2359 }
2360 return n;
2361}
24072362
2408 const have_pread_but_not_preadv = switch (native_os) {2363fn fileReadPositionalPosix(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset: u64) Io.File.ReadPositionalError!usize {
2409 .windows, .haiku, .serenity => true,2364 const t: *Threaded = @ptrCast(@alignCast(userdata));
2410 else => false,2365
2411 };2366 if (!have_preadv) @compileError("TODO");
2412 if (have_pread_but_not_preadv) {
2413 @compileError("TODO");
2414 }
24152367
2416 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;2368 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;
2417 var i: usize = 0;2369 var i: usize = 0;
...@@ -2480,6 +2432,48 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset...@@ -2480,6 +2432,48 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset
2480 }2432 }
2481}2433}
24822434
2435fn fileReadPositionalWindows(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset: u64) Io.File.ReadPositionalError!usize {
2436 const t: *Threaded = @ptrCast(@alignCast(userdata));
2437 try t.checkCancel();
2438
2439 const DWORD = windows.DWORD;
2440 const OVERLAPPED = windows.OVERLAPPED;
2441
2442 var index: usize = 0;
2443 while (data[index].len == 0) index += 1;
2444
2445 const buffer = data[index];
2446 const want_read_count: DWORD = @min(std.math.maxInt(DWORD), buffer.len);
2447 var n: DWORD = undefined;
2448 var overlapped: OVERLAPPED = .{
2449 .Internal = 0,
2450 .InternalHigh = 0,
2451 .DUMMYUNIONNAME = .{
2452 .DUMMYSTRUCTNAME = .{
2453 .Offset = @as(u32, @truncate(offset)),
2454 .OffsetHigh = @as(u32, @truncate(offset >> 32)),
2455 },
2456 },
2457 .hEvent = null,
2458 };
2459
2460 if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, &overlapped) == 0) {
2461 switch (windows.GetLastError()) {
2462 .IO_PENDING => |err| return windows.errorBug(err),
2463 .OPERATION_ABORTED => return error.Canceled,
2464 .BROKEN_PIPE => return 0,
2465 .HANDLE_EOF => return 0,
2466 .NETNAME_DELETED => return error.ConnectionResetByPeer,
2467 .LOCK_VIOLATION => return error.LockViolation,
2468 .ACCESS_DENIED => return error.AccessDenied,
2469 .INVALID_HANDLE => return error.NotOpenForReading,
2470 else => |err| return windows.unexpectedError(err),
2471 }
2472 }
2473
2474 return n;
2475}
2476
2483fn fileSeekBy(userdata: ?*anyopaque, file: Io.File, offset: i64) Io.File.SeekError!void {2477fn fileSeekBy(userdata: ?*anyopaque, file: Io.File, offset: i64) Io.File.SeekError!void {
2484 const t: *Threaded = @ptrCast(@alignCast(userdata));2478 const t: *Threaded = @ptrCast(@alignCast(userdata));
2485 try t.checkCancel();2479 try t.checkCancel();
...@@ -2563,11 +2557,9 @@ fn openSelfExe(userdata: ?*anyopaque, flags: Io.File.OpenFlags) Io.File.OpenSelf...@@ -2563,11 +2557,9 @@ fn openSelfExe(userdata: ?*anyopaque, flags: Io.File.OpenFlags) Io.File.OpenSelf
2563 // the file, we can let the openFileW call follow the symlink for us.2557 // the file, we can let the openFileW call follow the symlink for us.
2564 const image_path_unicode_string = &windows.peb().ProcessParameters.ImagePathName;2558 const image_path_unicode_string = &windows.peb().ProcessParameters.ImagePathName;
2565 const image_path_name = image_path_unicode_string.Buffer.?[0 .. image_path_unicode_string.Length / 2 :0];2559 const image_path_name = image_path_unicode_string.Buffer.?[0 .. image_path_unicode_string.Length / 2 :0];
2566 const prefixed_path_w_array = try windows.wToPrefixedFileW(null, image_path_name);
2567 const prefixed_path_w = prefixed_path_w_array.span();
2568 const cwd_handle = std.os.windows.peb().ProcessParameters.CurrentDirectory.Handle;2560 const cwd_handle = std.os.windows.peb().ProcessParameters.CurrentDirectory.Handle;
25692561
2570 return dirOpenFileWindows(t, .{ .handle = cwd_handle }, prefixed_path_w, flags);2562 return dirOpenFileWindowsInner(t, .{ .handle = cwd_handle }, image_path_name, flags);
2571 }2563 }
2572 @panic("TODO");2564 @panic("TODO");
2573}2565}
...@@ -3493,7 +3485,16 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net....@@ -3493,7 +3485,16 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
3493 }3485 }
3494}3486}
34953487
3496fn netSend(3488fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
3489 if (!have_networking) return .{ error.NetworkDown, 0 };
3490 const t: *Threaded = @ptrCast(@alignCast(userdata));
3491 _ = t;
3492 _ = handle;
3493 _ = data;
3494 @panic("TODO");
3495}
3496
3497fn netSendPosix(
3497 userdata: ?*anyopaque,3498 userdata: ?*anyopaque,
3498 handle: net.Socket.Handle,3499 handle: net.Socket.Handle,
3499 messages: []net.OutgoingMessage,3500 messages: []net.OutgoingMessage,
...@@ -3504,9 +3505,9 @@ fn netSend(...@@ -3504,9 +3505,9 @@ fn netSend(
35043505
3505 const posix_flags: u32 =3506 const posix_flags: u32 =
3506 @as(u32, if (@hasDecl(posix.MSG, "CONFIRM") and flags.confirm) posix.MSG.CONFIRM else 0) |3507 @as(u32, if (@hasDecl(posix.MSG, "CONFIRM") and flags.confirm) posix.MSG.CONFIRM else 0) |
3507 @as(u32, if (flags.dont_route) posix.MSG.DONTROUTE else 0) |3508 @as(u32, if (@hasDecl(posix.MSG, "DONTROUTE") and flags.dont_route) posix.MSG.DONTROUTE else 0) |
3508 @as(u32, if (flags.eor) posix.MSG.EOR else 0) |3509 @as(u32, if (@hasDecl(posix.MSG, "EOR") and flags.eor) posix.MSG.EOR else 0) |
3509 @as(u32, if (flags.oob) posix.MSG.OOB else 0) |3510 @as(u32, if (@hasDecl(posix.MSG, "OOB") and flags.oob) posix.MSG.OOB else 0) |
3510 @as(u32, if (@hasDecl(posix.MSG, "FASTOPEN") and flags.fastopen) posix.MSG.FASTOPEN else 0) |3511 @as(u32, if (@hasDecl(posix.MSG, "FASTOPEN") and flags.fastopen) posix.MSG.FASTOPEN else 0) |
3511 posix.MSG.NOSIGNAL;3512 posix.MSG.NOSIGNAL;
35123513
...@@ -3522,6 +3523,21 @@ fn netSend(...@@ -3522,6 +3523,21 @@ fn netSend(
3522 return .{ null, i };3523 return .{ null, i };
3523}3524}
35243525
3526fn netSendWindows(
3527 userdata: ?*anyopaque,
3528 handle: net.Socket.Handle,
3529 messages: []net.OutgoingMessage,
3530 flags: net.SendFlags,
3531) struct { ?net.Socket.SendError, usize } {
3532 if (!have_networking) return .{ error.NetworkDown, 0 };
3533 const t: *Threaded = @ptrCast(@alignCast(userdata));
3534 _ = t;
3535 _ = handle;
3536 _ = messages;
3537 _ = flags;
3538 @panic("TODO");
3539}
3540
3525fn netSendOne(3541fn netSendOne(
3526 t: *Threaded,3542 t: *Threaded,
3527 handle: net.Socket.Handle,3543 handle: net.Socket.Handle,
...@@ -3676,7 +3692,7 @@ fn netSendMany(...@@ -3676,7 +3692,7 @@ fn netSendMany(
3676 }3692 }
3677}3693}
36783694
3679fn netReceive(3695fn netReceivePosix(
3680 userdata: ?*anyopaque,3696 userdata: ?*anyopaque,
3681 handle: net.Socket.Handle,3697 handle: net.Socket.Handle,
3682 message_buffer: []net.IncomingMessage,3698 message_buffer: []net.IncomingMessage,
...@@ -3805,6 +3821,25 @@ fn netReceive(...@@ -3805,6 +3821,25 @@ fn netReceive(
3805 }3821 }
3806}3822}
38073823
3824fn netReceiveWindows(
3825 userdata: ?*anyopaque,
3826 handle: net.Socket.Handle,
3827 message_buffer: []net.IncomingMessage,
3828 data_buffer: []u8,
3829 flags: net.ReceiveFlags,
3830 timeout: Io.Timeout,
3831) struct { ?net.Socket.ReceiveTimeoutError, usize } {
3832 if (!have_networking) return .{ error.NetworkDown, 0 };
3833 const t: *Threaded = @ptrCast(@alignCast(userdata));
3834 _ = t;
3835 _ = handle;
3836 _ = message_buffer;
3837 _ = data_buffer;
3838 _ = flags;
3839 _ = timeout;
3840 @panic("TODO");
3841}
3842
3808fn netWritePosix(3843fn netWritePosix(
3809 userdata: ?*anyopaque,3844 userdata: ?*anyopaque,
3810 fd: net.Socket.Handle,3845 fd: net.Socket.Handle,
...@@ -3887,6 +3922,22 @@ fn netWritePosix(...@@ -3887,6 +3922,22 @@ fn netWritePosix(
3887 }3922 }
3888}3923}
38893924
3925fn netWriteWindows(
3926 userdata: ?*anyopaque,
3927 handle: net.Socket.Handle,
3928 header: []const u8,
3929 data: []const []const u8,
3930 splat: usize,
3931) net.Stream.Writer.Error!usize {
3932 const t: *Threaded = @ptrCast(@alignCast(userdata));
3933 _ = t;
3934 _ = handle;
3935 _ = header;
3936 _ = data;
3937 _ = splat;
3938 @panic("TODO");
3939}
3940
3890fn addBuf(v: []posix.iovec_const, i: *@FieldType(posix.msghdr_const, "iovlen"), bytes: []const u8) void {3941fn addBuf(v: []posix.iovec_const, i: *@FieldType(posix.msghdr_const, "iovlen"), bytes: []const u8) void {
3891 // OS checks ptr addr before length so zero length vectors must be omitted.3942 // OS checks ptr addr before length so zero length vectors must be omitted.
3892 if (bytes.len == 0) return;3943 if (bytes.len == 0) return;
...@@ -3899,7 +3950,7 @@ fn netClose(userdata: ?*anyopaque, handle: net.Socket.Handle) void {...@@ -3899,7 +3950,7 @@ fn netClose(userdata: ?*anyopaque, handle: net.Socket.Handle) void {
3899 const t: *Threaded = @ptrCast(@alignCast(userdata));3950 const t: *Threaded = @ptrCast(@alignCast(userdata));
3900 _ = t;3951 _ = t;
3901 switch (native_os) {3952 switch (native_os) {
3902 .windows => closeSocketWindows(handle) catch recoverableOsBugDetected(),3953 .windows => closeSocketWindows(handle),
3903 else => posix.close(handle),3954 else => posix.close(handle),
3904 }3955 }
3905}3956}
...@@ -4559,7 +4610,7 @@ fn lookupDns(...@@ -4559,7 +4610,7 @@ fn lookupDns(
4559 message_i += 1;4610 message_i += 1;
4560 }4611 }
4561 }4612 }
4562 _ = netSend(t, socket.handle, message_buffer[0..message_i], .{});4613 _ = netSendPosix(t, socket.handle, message_buffer[0..message_i], .{});
4563 }4614 }
45644615
4565 const timeout: Io.Timeout = .{ .deadline = .{4616 const timeout: Io.Timeout = .{ .deadline = .{
...@@ -4607,7 +4658,7 @@ fn lookupDns(...@@ -4607,7 +4658,7 @@ fn lookupDns(
4607 .data_ptr = query.ptr,4658 .data_ptr = query.ptr,
4608 .data_len = query.len,4659 .data_len = query.len,
4609 };4660 };
4610 _ = netSend(t, socket.handle, (&retry_message)[0..1], .{});4661 _ = netSendPosix(t, socket.handle, (&retry_message)[0..1], .{});
4611 continue;4662 continue;
4612 },4663 },
4613 else => continue,4664 else => continue,
...@@ -5157,9 +5208,9 @@ fn closeSocketWindows(s: ws2_32.SOCKET) void {...@@ -5157,9 +5208,9 @@ fn closeSocketWindows(s: ws2_32.SOCKET) void {
5157 if (builtin.mode == .Debug) switch (rc) {5208 if (builtin.mode == .Debug) switch (rc) {
5158 0 => {},5209 0 => {},
5159 ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) {5210 ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) {
5160 else => unreachable,5211 else => recoverableOsBugDetected(),
5161 },5212 },
5162 else => unreachable,5213 else => recoverableOsBugDetected(),
5163 };5214 };
5164}5215}
51655216
lib/std/Io/net/test.zig-18
...@@ -186,15 +186,6 @@ test "listen on a port, send bytes, receive bytes" {...@@ -186,15 +186,6 @@ test "listen on a port, send bytes, receive bytes" {
186186
187 const io = testing.io;187 const io = testing.io;
188188
189 if (builtin.os.tag == .windows) {
190 _ = try std.os.windows.WSAStartup(2, 2);
191 }
192 defer {
193 if (builtin.os.tag == .windows) {
194 std.os.windows.WSACleanup() catch unreachable;
195 }
196 }
197
198 // Try only the IPv4 variant as some CI builders have no IPv6 localhost189 // Try only the IPv4 variant as some CI builders have no IPv6 localhost
199 // configured.190 // configured.
200 const localhost: net.IpAddress = .{ .ip4 = .loopback(0) };191 const localhost: net.IpAddress = .{ .ip4 = .loopback(0) };
...@@ -282,15 +273,6 @@ test "listen on a unix socket, send bytes, receive bytes" {...@@ -282,15 +273,6 @@ test "listen on a unix socket, send bytes, receive bytes" {
282273
283 const io = testing.io;274 const io = testing.io;
284275
285 if (builtin.os.tag == .windows) {
286 _ = try std.os.windows.WSAStartup(2, 2);
287 }
288 defer {
289 if (builtin.os.tag == .windows) {
290 std.os.windows.WSACleanup() catch unreachable;
291 }
292 }
293
294 const socket_path = try generateFileName("socket.unix");276 const socket_path = try generateFileName("socket.unix");
295 defer testing.allocator.free(socket_path);277 defer testing.allocator.free(socket_path);
296278
lib/std/crypto/Certificate/Bundle.zig+4-2
...@@ -144,10 +144,12 @@ fn rescanWithPath(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp, cert_f...@@ -144,10 +144,12 @@ fn rescanWithPath(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp, cert_f
144144
145const RescanWindowsError = Allocator.Error || ParseCertError || std.posix.UnexpectedError || error{FileNotFound};145const RescanWindowsError = Allocator.Error || ParseCertError || std.posix.UnexpectedError || error{FileNotFound};
146146
147fn rescanWindows(cb: *Bundle, gpa: Allocator) RescanWindowsError!void {147fn rescanWindows(cb: *Bundle, gpa: Allocator, io: Io, now: Io.Timestamp) RescanWindowsError!void {
148 cb.bytes.clearRetainingCapacity();148 cb.bytes.clearRetainingCapacity();
149 cb.map.clearRetainingCapacity();149 cb.map.clearRetainingCapacity();
150150
151 _ = io;
152
151 const w = std.os.windows;153 const w = std.os.windows;
152 const GetLastError = w.GetLastError;154 const GetLastError = w.GetLastError;
153 const root = [4:0]u16{ 'R', 'O', 'O', 'T' };155 const root = [4:0]u16{ 'R', 'O', 'O', 'T' };
...@@ -157,7 +159,7 @@ fn rescanWindows(cb: *Bundle, gpa: Allocator) RescanWindowsError!void {...@@ -157,7 +159,7 @@ fn rescanWindows(cb: *Bundle, gpa: Allocator) RescanWindowsError!void {
157 };159 };
158 defer _ = w.crypt32.CertCloseStore(store, 0);160 defer _ = w.crypt32.CertCloseStore(store, 0);
159161
160 const now_sec = std.time.timestamp();162 const now_sec = now.toSeconds();
161163
162 var ctx = w.crypt32.CertEnumCertificatesInStore(store, null);164 var ctx = w.crypt32.CertEnumCertificatesInStore(store, null);
163 while (ctx) |context| : (ctx = w.crypt32.CertEnumCertificatesInStore(store, ctx)) {165 while (ctx) |context| : (ctx = w.crypt32.CertEnumCertificatesInStore(store, ctx)) {
lib/std/os/windows.zig+7
...@@ -2735,6 +2735,13 @@ pub fn statusBug(status: NTSTATUS) UnexpectedError {...@@ -2735,6 +2735,13 @@ pub fn statusBug(status: NTSTATUS) UnexpectedError {
2735 }2735 }
2736}2736}
27372737
2738pub fn errorBug(err: Win32Error) UnexpectedError {
2739 switch (builtin.mode) {
2740 .Debug => std.debug.panic("programmer bug caused syscall status: {t}", .{err}),
2741 else => return error.Unexpected,
2742 }
2743}
2744
2738pub const Win32Error = @import("windows/win32error.zig").Win32Error;2745pub const Win32Error = @import("windows/win32error.zig").Win32Error;
2739pub const NTSTATUS = @import("windows/ntstatus.zig").NTSTATUS;2746pub const NTSTATUS = @import("windows/ntstatus.zig").NTSTATUS;
2740pub const LANG = @import("windows/lang.zig");2747pub const LANG = @import("windows/lang.zig");