authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-12-29 19:09:53+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-01-03 15:45:10+00:00
loga1d4120fd9a3b34bde79d34dd14725d751021fc6
tree114bb8c6103067852540a8de1859c84e7c649a33
parent0da5d5f15063455eaab9a350352914a062cf18e2
signaturelock-open Commit is signed but in an unrecognized format.

std.Io.Threaded: update to new internal syscall API


1 files changed, 1022 insertions(+), 1070 deletions(-)

lib/std/Io/Threaded.zig+1022-1070
...@@ -321,14 +321,7 @@ const Group = struct {...@@ -321,14 +321,7 @@ const Group = struct {
321 var timeout_ns: u64 = 1 << 10;321 var timeout_ns: u64 = 1 << 10;
322 while (true) {322 while (true) {
323 need_signal = need_signal and g.signalAllCanceledSyscalls(t) and t.robust_cancel == .enabled;323 need_signal = need_signal and g.signalAllCanceledSyscalls(t) and t.robust_cancel == .enabled;
324 Thread.futexWaitTimed(324 Thread.futexWaitUncancelable(&num_completed.raw, 0, if (need_signal) timeout_ns else null);
325 null,
326 &num_completed.raw,
327 0,
328 if (need_signal) timeout_ns else null,
329 ) catch |err| switch (err) {
330 error.Canceled => unreachable,
331 };
332 switch (num_completed.load(.acquire)) { // acquire task results325 switch (num_completed.load(.acquire)) { // acquire task results
333 0 => {},326 0 => {},
334 1 => break,327 1 => break,
...@@ -482,14 +475,7 @@ const Future = struct {...@@ -482,14 +475,7 @@ const Future = struct {
482 var timeout_ns: u64 = 1 << 10;475 var timeout_ns: u64 = 1 << 10;
483 while (true) {476 while (true) {
484 need_signal = need_signal and thread.?.signalCanceledSyscall(t, .fromFuture(future)) and t.robust_cancel == .enabled;477 need_signal = need_signal and thread.?.signalCanceledSyscall(t, .fromFuture(future)) and t.robust_cancel == .enabled;
485 Thread.futexWaitTimed(478 Thread.futexWaitUncancelable(&num_completed.raw, 0, if (need_signal) timeout_ns else null);
486 null,
487 &num_completed.raw,
488 0,
489 if (need_signal) timeout_ns else null,
490 ) catch |err| switch (err) {
491 error.Canceled => unreachable,
492 };
493 switch (num_completed.load(.acquire)) { // acquire task results479 switch (num_completed.load(.acquire)) { // acquire task results
494 0 => {},480 0 => {},
495 1 => break,481 1 => break,
...@@ -615,22 +601,22 @@ const Thread = struct {...@@ -615,22 +601,22 @@ const Thread = struct {
615 return if (std.Thread.use_pthreads) std.c.pthread_self() else std.Thread.getCurrentId();601 return if (std.Thread.use_pthreads) std.c.pthread_self() else std.Thread.getCurrentId();
616 }602 }
617603
618 fn futexWaitUncancelable(ptr: *const u32, expect: u32) void {604 fn futexWaitUncancelable(ptr: *const u32, expect: u32, timeout_ns: ?u64) void {
619 return Thread.futexWaitTimed(null, ptr, expect, null) catch unreachable;605 return Thread.futexWaitInner(ptr, expect, true, timeout_ns) catch unreachable;
620 }606 }
621607
622 fn futexWait(thread: *Thread, ptr: *const u32, expect: u32) Io.Cancelable!void {608 fn futexWait(ptr: *const u32, expect: u32, timeout_ns: ?u64) Io.Cancelable!void {
623 return Thread.futexWaitTimed(thread, ptr, expect, null);609 return Thread.futexWaitInner(ptr, expect, false, timeout_ns);
624 }610 }
625611
626 fn futexWaitTimed(thread: ?*Thread, ptr: *const u32, expect: u32, timeout_ns: ?u64) Io.Cancelable!void {612 fn futexWaitInner(ptr: *const u32, expect: u32, uncancelable: bool, timeout_ns: ?u64) Io.Cancelable!void {
627 @branchHint(.cold);613 @branchHint(.cold);
628614
629 if (builtin.single_threaded) unreachable; // nobody would ever wake us615 if (builtin.single_threaded) unreachable; // nobody would ever wake us
630616
631 if (builtin.cpu.arch.isWasm()) {617 if (builtin.cpu.arch.isWasm()) {
632 comptime assert(builtin.cpu.has(.wasm, .atomics));618 comptime assert(builtin.cpu.has(.wasm, .atomics));
633 if (thread) |t| try t.checkCancel();619 if (!uncancelable) try Thread.checkCancel();
634 const to: i64 = if (timeout_ns) |ns| ns else -1;620 const to: i64 = if (timeout_ns) |ns| ns else -1;
635 const signed_expect: i32 = @bitCast(expect);621 const signed_expect: i32 = @bitCast(expect);
636 const result = asm volatile (622 const result = asm volatile (
...@@ -658,9 +644,9 @@ const Thread = struct {...@@ -658,9 +644,9 @@ const Thread = struct {
658 ts_buffer = timestampToPosix(ns);644 ts_buffer = timestampToPosix(ns);
659 break :ts &ts_buffer;645 break :ts &ts_buffer;
660 } else null;646 } else null;
661 if (thread) |t| try t.beginSyscall();647 const syscall: Syscall = if (uncancelable) .{ .thread = null } else try .start();
662 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, ts);648 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, ts);
663 if (thread) |t| t.endSyscall();649 syscall.finish();
664 switch (linux.errno(rc)) {650 switch (linux.errno(rc)) {
665 .SUCCESS => {}, // notified by `wake()`651 .SUCCESS => {}, // notified by `wake()`
666 .INTR => {}, // caller's responsibility to retry652 .INTR => {}, // caller's responsibility to retry
...@@ -677,7 +663,7 @@ const Thread = struct {...@@ -677,7 +663,7 @@ const Thread = struct {
677 .op = .COMPARE_AND_WAIT,663 .op = .COMPARE_AND_WAIT,
678 .NO_ERRNO = true,664 .NO_ERRNO = true,
679 };665 };
680 if (thread) |t| try t.beginSyscall();666 const syscall: Syscall = if (uncancelable) .{ .thread = null } else try .start();
681 const status = switch (darwin_supports_ulock_wait2) {667 const status = switch (darwin_supports_ulock_wait2) {
682 true => c.__ulock_wait2(flags, ptr, expect, ns: {668 true => c.__ulock_wait2(flags, ptr, expect, ns: {
683 const ns = timeout_ns orelse break :ns 0;669 const ns = timeout_ns orelse break :ns 0;
...@@ -691,7 +677,7 @@ const Thread = struct {...@@ -691,7 +677,7 @@ const Thread = struct {
691 break :us us;677 break :us us;
692 }),678 }),
693 };679 };
694 if (thread) |t| t.endSyscall();680 syscall.finish();
695 if (status >= 0) return;681 if (status >= 0) return;
696 switch (@as(c.E, @enumFromInt(-status))) {682 switch (@as(c.E, @enumFromInt(-status))) {
697 .INTR => {}, // spurious wake683 .INTR => {}, // spurious wake
...@@ -713,7 +699,7 @@ const Thread = struct {...@@ -713,7 +699,7 @@ const Thread = struct {
713 timeout_value = -timeout_value;699 timeout_value = -timeout_value;
714 timeout_ptr = &timeout_value;700 timeout_ptr = &timeout_value;
715 }701 }
716 if (thread) |t| try t.checkCancel();702 if (!uncancelable) try Thread.checkCancel();
717 switch (windows.ntdll.RtlWaitOnAddress(ptr, &expect, @sizeOf(@TypeOf(expect)), timeout_ptr)) {703 switch (windows.ntdll.RtlWaitOnAddress(ptr, &expect, @sizeOf(@TypeOf(expect)), timeout_ptr)) {
718 .SUCCESS => {},704 .SUCCESS => {},
719 .CANCELLED => {},705 .CANCELLED => {},
...@@ -733,9 +719,9 @@ const Thread = struct {...@@ -733,9 +719,9 @@ const Thread = struct {
733 tm.clockid = .MONOTONIC;719 tm.clockid = .MONOTONIC;
734 tm.timeout = timestampToPosix(ns);720 tm.timeout = timestampToPosix(ns);
735 }721 }
736 if (thread) |t| try t.beginSyscall();722 const syscall: Syscall = if (uncancelable) .{ .thread = null } else try .start();
737 const rc = std.c._umtx_op(@intFromPtr(ptr), flags, @as(c_ulong, expect), tm_size, @intFromPtr(tm_ptr));723 const rc = std.c._umtx_op(@intFromPtr(ptr), flags, @as(c_ulong, expect), tm_size, @intFromPtr(tm_ptr));
738 if (thread) |t| t.endSyscall();724 syscall.finish();
739 if (is_debug) switch (posix.errno(rc)) {725 if (is_debug) switch (posix.errno(rc)) {
740 .SUCCESS => {},726 .SUCCESS => {},
741 .FAULT => unreachable, // one of the args points to invalid memory727 .FAULT => unreachable, // one of the args points to invalid memory
...@@ -1821,7 +1807,6 @@ fn groupAwait(userdata: ?*anyopaque, type_erased: *Io.Group, initial_token: *any...@@ -1821,7 +1807,6 @@ fn groupAwait(userdata: ?*anyopaque, type_erased: *Io.Group, initial_token: *any
1821 _ = initial_token; // we need to load `token` *after* the group finishes1807 _ = initial_token; // we need to load `token` *after* the group finishes
1822 const t: *Threaded = @ptrCast(@alignCast(userdata));1808 const t: *Threaded = @ptrCast(@alignCast(userdata));
1823 const g: Group = .{ .ptr = type_erased };1809 const g: Group = .{ .ptr = type_erased };
1824 const thread: *Thread = .getCurrent(t);
18251810
1826 var num_completed: std.atomic.Value(u32) = .init(0);1811 var num_completed: std.atomic.Value(u32) = .init(0);
1827 g.awaiter().* = &num_completed;1812 g.awaiter().* = &num_completed;
...@@ -1841,7 +1826,7 @@ fn groupAwait(userdata: ?*anyopaque, type_erased: *Io.Group, initial_token: *any...@@ -1841,7 +1826,7 @@ fn groupAwait(userdata: ?*anyopaque, type_erased: *Io.Group, initial_token: *any
1841 return;1826 return;
1842 }1827 }
18431828
1844 while (thread.futexWait(&num_completed.raw, 0)) {1829 while (Thread.futexWait(&num_completed.raw, 0, null)) {
1845 switch (num_completed.load(.acquire)) { // acquire task results1830 switch (num_completed.load(.acquire)) { // acquire task results
1846 0 => continue,1831 0 => continue,
1847 1 => break,1832 1 => break,
...@@ -1907,8 +1892,9 @@ fn groupCancel(userdata: ?*anyopaque, type_erased: *Io.Group, initial_token: *an...@@ -1907,8 +1892,9 @@ fn groupCancel(userdata: ?*anyopaque, type_erased: *Io.Group, initial_token: *an
19071892
1908fn recancel(userdata: ?*anyopaque) void {1893fn recancel(userdata: ?*anyopaque) void {
1909 const t: *Threaded = @ptrCast(@alignCast(userdata));1894 const t: *Threaded = @ptrCast(@alignCast(userdata));
1910 const current_thread: *Thread = .getCurrent(t);1895 _ = t;
1911 switch (current_thread.status.fetchXor(.{1896 const thread = Thread.current.?; // called `recancel` but was not canceled
1897 switch (thread.status.fetchXor(.{
1912 .cancelation = @enumFromInt(0b001),1898 .cancelation = @enumFromInt(0b001),
1913 .awaitable = .null,1899 .awaitable = .null,
1914 }, .monotonic).cancelation) {1900 }, .monotonic).cancelation) {
...@@ -1924,9 +1910,10 @@ fn recancel(userdata: ?*anyopaque) void {...@@ -1924,9 +1910,10 @@ fn recancel(userdata: ?*anyopaque) void {
19241910
1925fn swapCancelProtection(userdata: ?*anyopaque, new: Io.CancelProtection) Io.CancelProtection {1911fn swapCancelProtection(userdata: ?*anyopaque, new: Io.CancelProtection) Io.CancelProtection {
1926 const t: *Threaded = @ptrCast(@alignCast(userdata));1912 const t: *Threaded = @ptrCast(@alignCast(userdata));
1927 const current_thread: *Thread = .getCurrent(t);1913 _ = t;
1928 const old = current_thread.cancel_protection;1914 const thread = Thread.current orelse return .unblocked;
1929 current_thread.cancel_protection = new;1915 const old = thread.cancel_protection;
1916 thread.cancel_protection = new;
1930 return old;1917 return old;
1931}1918}
19321919
...@@ -1945,7 +1932,6 @@ fn await(...@@ -1945,7 +1932,6 @@ fn await(
1945 _ = result_alignment;1932 _ = result_alignment;
1946 const t: *Threaded = @ptrCast(@alignCast(userdata));1933 const t: *Threaded = @ptrCast(@alignCast(userdata));
1947 const future: *Future = @ptrCast(@alignCast(any_future));1934 const future: *Future = @ptrCast(@alignCast(any_future));
1948 const thread: *Thread = .getCurrent(t);
19491935
1950 var num_completed: std.atomic.Value(u32) = .init(0);1936 var num_completed: std.atomic.Value(u32) = .init(0);
1951 future.awaiter = &num_completed;1937 future.awaiter = &num_completed;
...@@ -1955,7 +1941,7 @@ fn await(...@@ -1955,7 +1941,7 @@ fn await(
1955 .thread = .null,1941 .thread = .null,
1956 }, .acq_rel); // acquire results if complete; release `future.awaiter`1942 }, .acq_rel); // acquire results if complete; release `future.awaiter`
1957 switch (pre_await_status.tag) {1943 switch (pre_await_status.tag) {
1958 .pending => while (thread.futexWait(&num_completed.raw, 0)) {1944 .pending => while (Thread.futexWait(&num_completed.raw, 0, null)) {
1959 switch (num_completed.load(.acquire)) { // acquire task results1945 switch (num_completed.load(.acquire)) { // acquire task results
1960 0 => continue,1946 0 => continue,
1961 1 => break,1947 1 => break,
...@@ -2024,20 +2010,19 @@ fn cancel(...@@ -2024,20 +2010,19 @@ fn cancel(
2024fn futexWait(userdata: ?*anyopaque, ptr: *const u32, expected: u32, timeout: Io.Timeout) Io.Cancelable!void {2010fn futexWait(userdata: ?*anyopaque, ptr: *const u32, expected: u32, timeout: Io.Timeout) Io.Cancelable!void {
2025 if (builtin.single_threaded) unreachable; // Deadlock.2011 if (builtin.single_threaded) unreachable; // Deadlock.
2026 const t: *Threaded = @ptrCast(@alignCast(userdata));2012 const t: *Threaded = @ptrCast(@alignCast(userdata));
2027 const current_thread = Thread.getCurrent(t);
2028 const t_io = ioBasic(t);2013 const t_io = ioBasic(t);
2029 const timeout_ns: ?u64 = ns: {2014 const timeout_ns: ?u64 = ns: {
2030 const d = (timeout.toDurationFromNow(t_io) catch break :ns 10) orelse break :ns null;2015 const d = (timeout.toDurationFromNow(t_io) catch break :ns 10) orelse break :ns null;
2031 break :ns std.math.lossyCast(u64, d.raw.toNanoseconds());2016 break :ns std.math.lossyCast(u64, d.raw.toNanoseconds());
2032 };2017 };
2033 return Thread.futexWaitTimed(current_thread, ptr, expected, timeout_ns);2018 return Thread.futexWait(ptr, expected, timeout_ns);
2034}2019}
20352020
2036fn futexWaitUncancelable(userdata: ?*anyopaque, ptr: *const u32, expected: u32) void {2021fn futexWaitUncancelable(userdata: ?*anyopaque, ptr: *const u32, expected: u32) void {
2037 if (builtin.single_threaded) unreachable; // Deadlock.2022 if (builtin.single_threaded) unreachable; // Deadlock.
2038 const t: *Threaded = @ptrCast(@alignCast(userdata));2023 const t: *Threaded = @ptrCast(@alignCast(userdata));
2039 _ = t;2024 _ = t;
2040 Thread.futexWaitUncancelable(ptr, expected);2025 Thread.futexWaitUncancelable(ptr, expected, null);
2041}2026}
20422027
2043fn futexWake(userdata: ?*anyopaque, ptr: *const u32, max_waiters: u32) void {2028fn futexWake(userdata: ?*anyopaque, ptr: *const u32, max_waiters: u32) void {
...@@ -2055,24 +2040,24 @@ const dirCreateDir = switch (native_os) {...@@ -2055,24 +2040,24 @@ const dirCreateDir = switch (native_os) {
20552040
2056fn dirCreateDirPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void {2041fn dirCreateDirPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void {
2057 const t: *Threaded = @ptrCast(@alignCast(userdata));2042 const t: *Threaded = @ptrCast(@alignCast(userdata));
2058 const current_thread = Thread.getCurrent(t);2043 _ = t;
20592044
2060 var path_buffer: [posix.PATH_MAX]u8 = undefined;2045 var path_buffer: [posix.PATH_MAX]u8 = undefined;
2061 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);2046 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
20622047
2063 try current_thread.beginSyscall();2048 const syscall: Syscall = try .start();
2064 while (true) {2049 while (true) {
2065 switch (posix.errno(posix.system.mkdirat(dir.handle, sub_path_posix, permissions.toMode()))) {2050 switch (posix.errno(posix.system.mkdirat(dir.handle, sub_path_posix, permissions.toMode()))) {
2066 .SUCCESS => {2051 .SUCCESS => {
2067 current_thread.endSyscall();2052 syscall.finish();
2068 return;2053 return;
2069 },2054 },
2070 .INTR => {2055 .INTR => {
2071 try current_thread.checkCancel();2056 try syscall.checkCancel();
2072 continue;2057 continue;
2073 },2058 },
2074 else => |e| {2059 else => |e| {
2075 current_thread.endSyscall();2060 syscall.finish();
2076 switch (e) {2061 switch (e) {
2077 .ACCES => return error.AccessDenied,2062 .ACCES => return error.AccessDenied,
2078 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2063 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2101,20 +2086,20 @@ fn dirCreateDirPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, perm...@@ -2101,20 +2086,20 @@ fn dirCreateDirPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, perm
2101fn dirCreateDirWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void {2086fn dirCreateDirWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void {
2102 if (builtin.link_libc) return dirCreateDirPosix(userdata, dir, sub_path, permissions);2087 if (builtin.link_libc) return dirCreateDirPosix(userdata, dir, sub_path, permissions);
2103 const t: *Threaded = @ptrCast(@alignCast(userdata));2088 const t: *Threaded = @ptrCast(@alignCast(userdata));
2104 const current_thread = Thread.getCurrent(t);2089 _ = t;
2105 try current_thread.beginSyscall();2090 const syscall: Syscall = try .start();
2106 while (true) {2091 while (true) {
2107 switch (std.os.wasi.path_create_directory(dir.handle, sub_path.ptr, sub_path.len)) {2092 switch (std.os.wasi.path_create_directory(dir.handle, sub_path.ptr, sub_path.len)) {
2108 .SUCCESS => {2093 .SUCCESS => {
2109 current_thread.endSyscall();2094 syscall.finish();
2110 return;2095 return;
2111 },2096 },
2112 .INTR => {2097 .INTR => {
2113 try current_thread.checkCancel();2098 try syscall.checkCancel();
2114 continue;2099 continue;
2115 },2100 },
2116 else => |e| {2101 else => |e| {
2117 current_thread.endSyscall();2102 syscall.finish();
2118 switch (e) {2103 switch (e) {
2119 .ACCES => return error.AccessDenied,2104 .ACCES => return error.AccessDenied,
2120 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2105 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2141,8 +2126,8 @@ fn dirCreateDirWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permi...@@ -2141,8 +2126,8 @@ fn dirCreateDirWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permi
21412126
2142fn dirCreateDirWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void {2127fn dirCreateDirWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void {
2143 const t: *Threaded = @ptrCast(@alignCast(userdata));2128 const t: *Threaded = @ptrCast(@alignCast(userdata));
2144 const current_thread = Thread.getCurrent(t);2129 _ = t;
2145 try current_thread.checkCancel();2130 try Thread.checkCancel();
21462131
2147 const sub_path_w = try windows.sliceToPrefixedFileW(dir.handle, sub_path);2132 const sub_path_w = try windows.sliceToPrefixedFileW(dir.handle, sub_path);
2148 _ = permissions; // TODO use this value2133 _ = permissions; // TODO use this value
...@@ -2229,7 +2214,6 @@ fn dirCreateDirPathOpenWindows(...@@ -2229,7 +2214,6 @@ fn dirCreateDirPathOpenWindows(
2229 options: Dir.OpenOptions,2214 options: Dir.OpenOptions,
2230) Dir.CreateDirPathOpenError!Dir {2215) Dir.CreateDirPathOpenError!Dir {
2231 const t: *Threaded = @ptrCast(@alignCast(userdata));2216 const t: *Threaded = @ptrCast(@alignCast(userdata));
2232 const current_thread = Thread.getCurrent(t);
2233 const w = windows;2217 const w = windows;
22342218
2235 _ = permissions; // TODO apply these permissions2219 _ = permissions; // TODO apply these permissions
...@@ -2242,7 +2226,7 @@ fn dirCreateDirPathOpenWindows(...@@ -2242,7 +2226,7 @@ fn dirCreateDirPathOpenWindows(
2242 };2226 };
22432227
2244 while (true) {2228 while (true) {
2245 try current_thread.checkCancel();2229 try Thread.checkCancel();
22462230
2247 const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, component.path);2231 const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, component.path);
2248 const sub_path_w = sub_path_w_array.span();2232 const sub_path_w = sub_path_w_array.span();
...@@ -2371,7 +2355,7 @@ fn dirStatFileLinux(...@@ -2371,7 +2355,7 @@ fn dirStatFileLinux(
2371 options: Dir.StatFileOptions,2355 options: Dir.StatFileOptions,
2372) Dir.StatFileError!File.Stat {2356) Dir.StatFileError!File.Stat {
2373 const t: *Threaded = @ptrCast(@alignCast(userdata));2357 const t: *Threaded = @ptrCast(@alignCast(userdata));
2374 const current_thread = Thread.getCurrent(t);2358 _ = t;
2375 const linux = std.os.linux;2359 const linux = std.os.linux;
2376 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid())2360 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid())
2377 .{ .major = 30, .minor = 0, .patch = 0 }2361 .{ .major = 30, .minor = 0, .patch = 0 }
...@@ -2385,20 +2369,20 @@ fn dirStatFileLinux(...@@ -2385,20 +2369,20 @@ fn dirStatFileLinux(
2385 const flags: u32 = linux.AT.NO_AUTOMOUNT |2369 const flags: u32 = linux.AT.NO_AUTOMOUNT |
2386 @as(u32, if (!options.follow_symlinks) linux.AT.SYMLINK_NOFOLLOW else 0);2370 @as(u32, if (!options.follow_symlinks) linux.AT.SYMLINK_NOFOLLOW else 0);
23872371
2388 try current_thread.beginSyscall();2372 const syscall: Syscall = try .start();
2389 while (true) {2373 while (true) {
2390 var statx = std.mem.zeroes(linux.Statx);2374 var statx = std.mem.zeroes(linux.Statx);
2391 switch (sys.errno(sys.statx(dir.handle, sub_path_posix, flags, linux_statx_request, &statx))) {2375 switch (sys.errno(sys.statx(dir.handle, sub_path_posix, flags, linux_statx_request, &statx))) {
2392 .SUCCESS => {2376 .SUCCESS => {
2393 current_thread.endSyscall();2377 syscall.finish();
2394 return statFromLinux(&statx);2378 return statFromLinux(&statx);
2395 },2379 },
2396 .INTR => {2380 .INTR => {
2397 try current_thread.checkCancel();2381 try syscall.checkCancel();
2398 continue;2382 continue;
2399 },2383 },
2400 else => |e| {2384 else => |e| {
2401 current_thread.endSyscall();2385 syscall.finish();
2402 switch (e) {2386 switch (e) {
2403 .ACCES => return error.AccessDenied,2387 .ACCES => return error.AccessDenied,
2404 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2388 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2423,31 +2407,31 @@ fn dirStatFilePosix(...@@ -2423,31 +2407,31 @@ fn dirStatFilePosix(
2423 options: Dir.StatFileOptions,2407 options: Dir.StatFileOptions,
2424) Dir.StatFileError!File.Stat {2408) Dir.StatFileError!File.Stat {
2425 const t: *Threaded = @ptrCast(@alignCast(userdata));2409 const t: *Threaded = @ptrCast(@alignCast(userdata));
2426 const current_thread = Thread.getCurrent(t);2410 _ = t;
24272411
2428 var path_buffer: [posix.PATH_MAX]u8 = undefined;2412 var path_buffer: [posix.PATH_MAX]u8 = undefined;
2429 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);2413 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
24302414
2431 const flags: u32 = if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0;2415 const flags: u32 = if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0;
24322416
2433 return posixStatFile(current_thread, dir.handle, sub_path_posix, flags);2417 return posixStatFile(dir.handle, sub_path_posix, flags);
2434}2418}
24352419
2436fn posixStatFile(current_thread: *Thread, dir_fd: posix.fd_t, sub_path: [:0]const u8, flags: u32) Dir.StatFileError!File.Stat {2420fn posixStatFile(dir_fd: posix.fd_t, sub_path: [:0]const u8, flags: u32) Dir.StatFileError!File.Stat {
2437 try current_thread.beginSyscall();2421 const syscall: Syscall = try .start();
2438 while (true) {2422 while (true) {
2439 var stat = std.mem.zeroes(posix.Stat);2423 var stat = std.mem.zeroes(posix.Stat);
2440 switch (posix.errno(fstatat_sym(dir_fd, sub_path, &stat, flags))) {2424 switch (posix.errno(fstatat_sym(dir_fd, sub_path, &stat, flags))) {
2441 .SUCCESS => {2425 .SUCCESS => {
2442 current_thread.endSyscall();2426 syscall.finish();
2443 return statFromPosix(&stat);2427 return statFromPosix(&stat);
2444 },2428 },
2445 .INTR => {2429 .INTR => {
2446 try current_thread.checkCancel();2430 try syscall.checkCancel();
2447 continue;2431 continue;
2448 },2432 },
2449 else => |e| {2433 else => |e| {
2450 current_thread.endSyscall();2434 syscall.finish();
2451 switch (e) {2435 switch (e) {
2452 .INVAL => |err| return errnoBug(err),2436 .INVAL => |err| return errnoBug(err),
2453 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2437 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2489,25 +2473,25 @@ fn dirStatFileWasi(...@@ -2489,25 +2473,25 @@ fn dirStatFileWasi(
2489) Dir.StatFileError!File.Stat {2473) Dir.StatFileError!File.Stat {
2490 if (builtin.link_libc) return dirStatFilePosix(userdata, dir, sub_path, options);2474 if (builtin.link_libc) return dirStatFilePosix(userdata, dir, sub_path, options);
2491 const t: *Threaded = @ptrCast(@alignCast(userdata));2475 const t: *Threaded = @ptrCast(@alignCast(userdata));
2492 const current_thread = Thread.getCurrent(t);2476 _ = t;
2493 const wasi = std.os.wasi;2477 const wasi = std.os.wasi;
2494 const flags: wasi.lookupflags_t = .{2478 const flags: wasi.lookupflags_t = .{
2495 .SYMLINK_FOLLOW = options.follow_symlinks,2479 .SYMLINK_FOLLOW = options.follow_symlinks,
2496 };2480 };
2497 var stat: wasi.filestat_t = undefined;2481 var stat: wasi.filestat_t = undefined;
2498 try current_thread.beginSyscall();2482 const syscall: Syscall = try .start();
2499 while (true) {2483 while (true) {
2500 switch (wasi.path_filestat_get(dir.handle, flags, sub_path.ptr, sub_path.len, &stat)) {2484 switch (wasi.path_filestat_get(dir.handle, flags, sub_path.ptr, sub_path.len, &stat)) {
2501 .SUCCESS => {2485 .SUCCESS => {
2502 current_thread.endSyscall();2486 syscall.finish();
2503 return statFromWasi(&stat);2487 return statFromWasi(&stat);
2504 },2488 },
2505 .INTR => {2489 .INTR => {
2506 try current_thread.checkCancel();2490 try syscall.checkCancel();
2507 continue;2491 continue;
2508 },2492 },
2509 else => |e| {2493 else => |e| {
2510 current_thread.endSyscall();2494 syscall.finish();
2511 switch (e) {2495 switch (e) {
2512 .INVAL => |err| return errnoBug(err),2496 .INVAL => |err| return errnoBug(err),
2513 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2497 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2530,24 +2514,23 @@ fn fileLength(userdata: ?*anyopaque, file: File) File.LengthError!u64 {...@@ -2530,24 +2514,23 @@ fn fileLength(userdata: ?*anyopaque, file: File) File.LengthError!u64 {
2530 const t: *Threaded = @ptrCast(@alignCast(userdata));2514 const t: *Threaded = @ptrCast(@alignCast(userdata));
25312515
2532 if (native_os == .linux) {2516 if (native_os == .linux) {
2533 const current_thread = Thread.getCurrent(t);
2534 const linux = std.os.linux;2517 const linux = std.os.linux;
25352518
2536 try current_thread.beginSyscall();2519 const syscall: Syscall = try .start();
2537 while (true) {2520 while (true) {
2538 var statx = std.mem.zeroes(linux.Statx);2521 var statx = std.mem.zeroes(linux.Statx);
2539 switch (linux.errno(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, .{ .SIZE = true }, &statx))) {2522 switch (linux.errno(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, .{ .SIZE = true }, &statx))) {
2540 .SUCCESS => {2523 .SUCCESS => {
2541 current_thread.endSyscall();2524 syscall.finish();
2542 if (!statx.mask.SIZE) return error.Unexpected;2525 if (!statx.mask.SIZE) return error.Unexpected;
2543 return statx.size;2526 return statx.size;
2544 },2527 },
2545 .INTR => {2528 .INTR => {
2546 try current_thread.checkCancel();2529 try syscall.checkCancel();
2547 continue;2530 continue;
2548 },2531 },
2549 else => |e| {2532 else => |e| {
2550 current_thread.endSyscall();2533 syscall.finish();
2551 switch (e) {2534 switch (e) {
2552 .ACCES => |err| return errnoBug(err),2535 .ACCES => |err| return errnoBug(err),
2553 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2536 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2580,24 +2563,24 @@ const fileStat = switch (native_os) {...@@ -2580,24 +2563,24 @@ const fileStat = switch (native_os) {
25802563
2581fn fileStatPosix(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {2564fn fileStatPosix(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
2582 const t: *Threaded = @ptrCast(@alignCast(userdata));2565 const t: *Threaded = @ptrCast(@alignCast(userdata));
2583 const current_thread = Thread.getCurrent(t);2566 _ = t;
25842567
2585 if (posix.Stat == void) return error.Streaming;2568 if (posix.Stat == void) return error.Streaming;
25862569
2587 try current_thread.beginSyscall();2570 const syscall: Syscall = try .start();
2588 while (true) {2571 while (true) {
2589 var stat = std.mem.zeroes(posix.Stat);2572 var stat = std.mem.zeroes(posix.Stat);
2590 switch (posix.errno(fstat_sym(file.handle, &stat))) {2573 switch (posix.errno(fstat_sym(file.handle, &stat))) {
2591 .SUCCESS => {2574 .SUCCESS => {
2592 current_thread.endSyscall();2575 syscall.finish();
2593 return statFromPosix(&stat);2576 return statFromPosix(&stat);
2594 },2577 },
2595 .INTR => {2578 .INTR => {
2596 try current_thread.checkCancel();2579 try syscall.checkCancel();
2597 continue;2580 continue;
2598 },2581 },
2599 else => |e| {2582 else => |e| {
2600 current_thread.endSyscall();2583 syscall.finish();
2601 switch (e) {2584 switch (e) {
2602 .INVAL => |err| return errnoBug(err),2585 .INVAL => |err| return errnoBug(err),
2603 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2586 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2612,7 +2595,7 @@ fn fileStatPosix(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {...@@ -2612,7 +2595,7 @@ fn fileStatPosix(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
26122595
2613fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {2596fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
2614 const t: *Threaded = @ptrCast(@alignCast(userdata));2597 const t: *Threaded = @ptrCast(@alignCast(userdata));
2615 const current_thread = Thread.getCurrent(t);2598 _ = t;
2616 const linux = std.os.linux;2599 const linux = std.os.linux;
2617 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid())2600 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid())
2618 .{ .major = 30, .minor = 0, .patch = 0 }2601 .{ .major = 30, .minor = 0, .patch = 0 }
...@@ -2620,20 +2603,20 @@ fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {...@@ -2620,20 +2603,20 @@ fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
2620 .{ .major = 2, .minor = 28, .patch = 0 });2603 .{ .major = 2, .minor = 28, .patch = 0 });
2621 const sys = if (use_c) std.c else std.os.linux;2604 const sys = if (use_c) std.c else std.os.linux;
26222605
2623 try current_thread.beginSyscall();2606 const syscall: Syscall = try .start();
2624 while (true) {2607 while (true) {
2625 var statx = std.mem.zeroes(linux.Statx);2608 var statx = std.mem.zeroes(linux.Statx);
2626 switch (sys.errno(sys.statx(file.handle, "", linux.AT.EMPTY_PATH, linux_statx_request, &statx))) {2609 switch (sys.errno(sys.statx(file.handle, "", linux.AT.EMPTY_PATH, linux_statx_request, &statx))) {
2627 .SUCCESS => {2610 .SUCCESS => {
2628 current_thread.endSyscall();2611 syscall.finish();
2629 return statFromLinux(&statx);2612 return statFromLinux(&statx);
2630 },2613 },
2631 .INTR => {2614 .INTR => {
2632 try current_thread.checkCancel();2615 try syscall.checkCancel();
2633 continue;2616 continue;
2634 },2617 },
2635 else => |e| {2618 else => |e| {
2636 current_thread.endSyscall();2619 syscall.finish();
2637 switch (e) {2620 switch (e) {
2638 .ACCES => |err| return errnoBug(err),2621 .ACCES => |err| return errnoBug(err),
2639 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2622 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2653,8 +2636,8 @@ fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {...@@ -2653,8 +2636,8 @@ fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
26532636
2654fn fileStatWindows(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {2637fn fileStatWindows(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
2655 const t: *Threaded = @ptrCast(@alignCast(userdata));2638 const t: *Threaded = @ptrCast(@alignCast(userdata));
2656 const current_thread = Thread.getCurrent(t);2639 _ = t;
2657 try current_thread.checkCancel();2640 try Thread.checkCancel();
26582641
2659 var io_status_block: windows.IO_STATUS_BLOCK = undefined;2642 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
2660 var info: windows.FILE.ALL_INFORMATION = undefined;2643 var info: windows.FILE.ALL_INFORMATION = undefined;
...@@ -2702,22 +2685,22 @@ fn fileStatWasi(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {...@@ -2702,22 +2685,22 @@ fn fileStatWasi(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
2702 if (builtin.link_libc) return fileStatPosix(userdata, file);2685 if (builtin.link_libc) return fileStatPosix(userdata, file);
27032686
2704 const t: *Threaded = @ptrCast(@alignCast(userdata));2687 const t: *Threaded = @ptrCast(@alignCast(userdata));
2705 const current_thread = Thread.getCurrent(t);2688 _ = t;
27062689
2707 try current_thread.beginSyscall();2690 const syscall: Syscall = try .start();
2708 while (true) {2691 while (true) {
2709 var stat: std.os.wasi.filestat_t = undefined;2692 var stat: std.os.wasi.filestat_t = undefined;
2710 switch (std.os.wasi.fd_filestat_get(file.handle, &stat)) {2693 switch (std.os.wasi.fd_filestat_get(file.handle, &stat)) {
2711 .SUCCESS => {2694 .SUCCESS => {
2712 current_thread.endSyscall();2695 syscall.finish();
2713 return statFromWasi(&stat);2696 return statFromWasi(&stat);
2714 },2697 },
2715 .INTR => {2698 .INTR => {
2716 try current_thread.checkCancel();2699 try syscall.checkCancel();
2717 continue;2700 continue;
2718 },2701 },
2719 else => |e| {2702 else => |e| {
2720 current_thread.endSyscall();2703 syscall.finish();
2721 switch (e) {2704 switch (e) {
2722 .INVAL => |err| return errnoBug(err),2705 .INVAL => |err| return errnoBug(err),
2723 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2706 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2744,7 +2727,7 @@ fn dirAccessPosix(...@@ -2744,7 +2727,7 @@ fn dirAccessPosix(
2744 options: Dir.AccessOptions,2727 options: Dir.AccessOptions,
2745) Dir.AccessError!void {2728) Dir.AccessError!void {
2746 const t: *Threaded = @ptrCast(@alignCast(userdata));2729 const t: *Threaded = @ptrCast(@alignCast(userdata));
2747 const current_thread = Thread.getCurrent(t);2730 _ = t;
27482731
2749 var path_buffer: [posix.PATH_MAX]u8 = undefined;2732 var path_buffer: [posix.PATH_MAX]u8 = undefined;
2750 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);2733 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
...@@ -2756,19 +2739,19 @@ fn dirAccessPosix(...@@ -2756,19 +2739,19 @@ fn dirAccessPosix(
2756 @as(u32, if (options.write) posix.W_OK else 0) |2739 @as(u32, if (options.write) posix.W_OK else 0) |
2757 @as(u32, if (options.execute) posix.X_OK else 0);2740 @as(u32, if (options.execute) posix.X_OK else 0);
27582741
2759 try current_thread.beginSyscall();2742 const syscall: Syscall = try .start();
2760 while (true) {2743 while (true) {
2761 switch (posix.errno(posix.system.faccessat(dir.handle, sub_path_posix, mode, flags))) {2744 switch (posix.errno(posix.system.faccessat(dir.handle, sub_path_posix, mode, flags))) {
2762 .SUCCESS => {2745 .SUCCESS => {
2763 current_thread.endSyscall();2746 syscall.finish();
2764 return;2747 return;
2765 },2748 },
2766 .INTR => {2749 .INTR => {
2767 try current_thread.checkCancel();2750 try syscall.checkCancel();
2768 continue;2751 continue;
2769 },2752 },
2770 else => |e| {2753 else => |e| {
2771 current_thread.endSyscall();2754 syscall.finish();
2772 switch (e) {2755 switch (e) {
2773 .ACCES => return error.AccessDenied,2756 .ACCES => return error.AccessDenied,
2774 .PERM => return error.PermissionDenied,2757 .PERM => return error.PermissionDenied,
...@@ -2798,26 +2781,26 @@ fn dirAccessWasi(...@@ -2798,26 +2781,26 @@ fn dirAccessWasi(
2798) Dir.AccessError!void {2781) Dir.AccessError!void {
2799 if (builtin.link_libc) return dirAccessPosix(userdata, dir, sub_path, options);2782 if (builtin.link_libc) return dirAccessPosix(userdata, dir, sub_path, options);
2800 const t: *Threaded = @ptrCast(@alignCast(userdata));2783 const t: *Threaded = @ptrCast(@alignCast(userdata));
2801 const current_thread = Thread.getCurrent(t);2784 _ = t;
2802 const wasi = std.os.wasi;2785 const wasi = std.os.wasi;
2803 const flags: wasi.lookupflags_t = .{2786 const flags: wasi.lookupflags_t = .{
2804 .SYMLINK_FOLLOW = options.follow_symlinks,2787 .SYMLINK_FOLLOW = options.follow_symlinks,
2805 };2788 };
2806 var stat: wasi.filestat_t = undefined;2789 var stat: wasi.filestat_t = undefined;
28072790
2808 try current_thread.beginSyscall();2791 const syscall: Syscall = try .start();
2809 while (true) {2792 while (true) {
2810 switch (wasi.path_filestat_get(dir.handle, flags, sub_path.ptr, sub_path.len, &stat)) {2793 switch (wasi.path_filestat_get(dir.handle, flags, sub_path.ptr, sub_path.len, &stat)) {
2811 .SUCCESS => {2794 .SUCCESS => {
2812 current_thread.endSyscall();2795 syscall.finish();
2813 break;2796 break;
2814 },2797 },
2815 .INTR => {2798 .INTR => {
2816 try current_thread.checkCancel();2799 try syscall.checkCancel();
2817 continue;2800 continue;
2818 },2801 },
2819 else => |e| {2802 else => |e| {
2820 current_thread.endSyscall();2803 syscall.finish();
2821 switch (e) {2804 switch (e) {
2822 .INVAL => |err| return errnoBug(err),2805 .INVAL => |err| return errnoBug(err),
2823 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2806 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -2869,8 +2852,8 @@ fn dirAccessWindows(...@@ -2869,8 +2852,8 @@ fn dirAccessWindows(
2869 options: Dir.AccessOptions,2852 options: Dir.AccessOptions,
2870) Dir.AccessError!void {2853) Dir.AccessError!void {
2871 const t: *Threaded = @ptrCast(@alignCast(userdata));2854 const t: *Threaded = @ptrCast(@alignCast(userdata));
2872 const current_thread = Thread.getCurrent(t);2855 _ = t;
2873 try current_thread.checkCancel();2856 try Thread.checkCancel();
28742857
2875 _ = options; // TODO2858 _ = options; // TODO
28762859
...@@ -2921,7 +2904,7 @@ fn dirCreateFilePosix(...@@ -2921,7 +2904,7 @@ fn dirCreateFilePosix(
2921 flags: File.CreateFlags,2904 flags: File.CreateFlags,
2922) File.OpenError!File {2905) File.OpenError!File {
2923 const t: *Threaded = @ptrCast(@alignCast(userdata));2906 const t: *Threaded = @ptrCast(@alignCast(userdata));
2924 const current_thread = Thread.getCurrent(t);2907 _ = t;
29252908
2926 var path_buffer: [posix.PATH_MAX]u8 = undefined;2909 var path_buffer: [posix.PATH_MAX]u8 = undefined;
2927 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);2910 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
...@@ -2950,49 +2933,51 @@ fn dirCreateFilePosix(...@@ -2950,49 +2933,51 @@ fn dirCreateFilePosix(
2950 },2933 },
2951 };2934 };
29522935
2953 try current_thread.beginSyscall();2936 const fd: posix.fd_t = fd: {
2954 const fd: posix.fd_t = while (true) {2937 const syscall: Syscall = try .start();
2955 const rc = openat_sym(dir.handle, sub_path_posix, os_flags, flags.permissions.toMode());2938 while (true) {
2956 switch (posix.errno(rc)) {2939 const rc = openat_sym(dir.handle, sub_path_posix, os_flags, flags.permissions.toMode());
2957 .SUCCESS => {2940 switch (posix.errno(rc)) {
2958 current_thread.endSyscall();2941 .SUCCESS => {
2959 break @intCast(rc);2942 syscall.finish();
2960 },2943 break :fd @intCast(rc);
2961 .INTR => {2944 },
2962 try current_thread.checkCancel();2945 .INTR => {
2963 continue;2946 try syscall.checkCancel();
2964 },2947 continue;
2965 else => |e| {2948 },
2966 current_thread.endSyscall();2949 else => |e| {
2967 switch (e) {2950 syscall.finish();
2968 .FAULT => |err| return errnoBug(err),2951 switch (e) {
2969 .INVAL => return error.BadPathName,2952 .FAULT => |err| return errnoBug(err),
2970 .BADF => |err| return errnoBug(err), // File descriptor used after closed.2953 .INVAL => return error.BadPathName,
2971 .ACCES => return error.AccessDenied,2954 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
2972 .FBIG => return error.FileTooBig,2955 .ACCES => return error.AccessDenied,
2973 .OVERFLOW => return error.FileTooBig,2956 .FBIG => return error.FileTooBig,
2974 .ISDIR => return error.IsDir,2957 .OVERFLOW => return error.FileTooBig,
2975 .LOOP => return error.SymLinkLoop,2958 .ISDIR => return error.IsDir,
2976 .MFILE => return error.ProcessFdQuotaExceeded,2959 .LOOP => return error.SymLinkLoop,
2977 .NAMETOOLONG => return error.NameTooLong,2960 .MFILE => return error.ProcessFdQuotaExceeded,
2978 .NFILE => return error.SystemFdQuotaExceeded,2961 .NAMETOOLONG => return error.NameTooLong,
2979 .NODEV => return error.NoDevice,2962 .NFILE => return error.SystemFdQuotaExceeded,
2980 .NOENT => return error.FileNotFound,2963 .NODEV => return error.NoDevice,
2981 .SRCH => return error.FileNotFound, // Linux when accessing procfs.2964 .NOENT => return error.FileNotFound,
2982 .NOMEM => return error.SystemResources,2965 .SRCH => return error.FileNotFound, // Linux when accessing procfs.
2983 .NOSPC => return error.NoSpaceLeft,2966 .NOMEM => return error.SystemResources,
2984 .NOTDIR => return error.NotDir,2967 .NOSPC => return error.NoSpaceLeft,
2985 .PERM => return error.PermissionDenied,2968 .NOTDIR => return error.NotDir,
2986 .EXIST => return error.PathAlreadyExists,2969 .PERM => return error.PermissionDenied,
2987 .BUSY => return error.DeviceBusy,2970 .EXIST => return error.PathAlreadyExists,
2988 .OPNOTSUPP => return error.FileLocksUnsupported,2971 .BUSY => return error.DeviceBusy,
2989 .AGAIN => return error.WouldBlock,2972 .OPNOTSUPP => return error.FileLocksUnsupported,
2990 .TXTBSY => return error.FileBusy,2973 .AGAIN => return error.WouldBlock,
2991 .NXIO => return error.NoDevice,2974 .TXTBSY => return error.FileBusy,
2992 .ILSEQ => return error.BadPathName,2975 .NXIO => return error.NoDevice,
2993 else => |err| return posix.unexpectedErrno(err),2976 .ILSEQ => return error.BadPathName,
2994 }2977 else => |err| return posix.unexpectedErrno(err),
2995 },2978 }
2979 },
2980 }
2996 }2981 }
2997 };2982 };
2998 errdefer posix.close(fd);2983 errdefer posix.close(fd);
...@@ -3005,19 +2990,19 @@ fn dirCreateFilePosix(...@@ -3005,19 +2990,19 @@ fn dirCreateFilePosix(
3005 .exclusive => posix.LOCK.EX | lock_nonblocking,2990 .exclusive => posix.LOCK.EX | lock_nonblocking,
3006 };2991 };
30072992
3008 try current_thread.beginSyscall();2993 const syscall: Syscall = try .start();
3009 while (true) {2994 while (true) {
3010 switch (posix.errno(posix.system.flock(fd, lock_flags))) {2995 switch (posix.errno(posix.system.flock(fd, lock_flags))) {
3011 .SUCCESS => {2996 .SUCCESS => {
3012 current_thread.endSyscall();2997 syscall.finish();
3013 break;2998 break;
3014 },2999 },
3015 .INTR => {3000 .INTR => {
3016 try current_thread.checkCancel();3001 try syscall.checkCancel();
3017 continue;3002 continue;
3018 },3003 },
3019 else => |e| {3004 else => |e| {
3020 current_thread.endSyscall();3005 syscall.finish();
3021 switch (e) {3006 switch (e) {
3022 .BADF => |err| return errnoBug(err), // File descriptor used after closed.3007 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
3023 .INVAL => |err| return errnoBug(err), // invalid parameters3008 .INVAL => |err| return errnoBug(err), // invalid parameters
...@@ -3032,40 +3017,42 @@ fn dirCreateFilePosix(...@@ -3032,40 +3017,42 @@ fn dirCreateFilePosix(
3032 }3017 }
30333018
3034 if (have_flock_open_flags and flags.lock_nonblocking) {3019 if (have_flock_open_flags and flags.lock_nonblocking) {
3035 try current_thread.beginSyscall();3020 var fl_flags: usize = fl: {
3036 var fl_flags: usize = while (true) {3021 const syscall: Syscall = try .start();
3037 const rc = posix.system.fcntl(fd, posix.F.GETFL, @as(usize, 0));3022 while (true) {
3038 switch (posix.errno(rc)) {3023 const rc = posix.system.fcntl(fd, posix.F.GETFL, @as(usize, 0));
3039 .SUCCESS => {3024 switch (posix.errno(rc)) {
3040 current_thread.endSyscall();3025 .SUCCESS => {
3041 break @intCast(rc);3026 syscall.finish();
3042 },3027 break :fl @intCast(rc);
3043 .INTR => {3028 },
3044 try current_thread.checkCancel();3029 .INTR => {
3045 continue;3030 try syscall.checkCancel();
3046 },3031 continue;
3047 else => |err| {3032 },
3048 current_thread.endSyscall();3033 else => |err| {
3049 return posix.unexpectedErrno(err);3034 syscall.finish();
3050 },3035 return posix.unexpectedErrno(err);
3036 },
3037 }
3051 }3038 }
3052 };3039 };
30533040
3054 fl_flags |= @as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK"));3041 fl_flags |= @as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK"));
30553042
3056 try current_thread.beginSyscall();3043 const syscall: Syscall = try .start();
3057 while (true) {3044 while (true) {
3058 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFL, fl_flags))) {3045 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFL, fl_flags))) {
3059 .SUCCESS => {3046 .SUCCESS => {
3060 current_thread.endSyscall();3047 syscall.finish();
3061 break;3048 break;
3062 },3049 },
3063 .INTR => {3050 .INTR => {
3064 try current_thread.checkCancel();3051 try syscall.checkCancel();
3065 continue;3052 continue;
3066 },3053 },
3067 else => |err| {3054 else => |err| {
3068 current_thread.endSyscall();3055 syscall.finish();
3069 return posix.unexpectedErrno(err);3056 return posix.unexpectedErrno(err);
3070 },3057 },
3071 }3058 }
...@@ -3083,8 +3070,8 @@ fn dirCreateFileWindows(...@@ -3083,8 +3070,8 @@ fn dirCreateFileWindows(
3083) File.OpenError!File {3070) File.OpenError!File {
3084 const w = windows;3071 const w = windows;
3085 const t: *Threaded = @ptrCast(@alignCast(userdata));3072 const t: *Threaded = @ptrCast(@alignCast(userdata));
3086 const current_thread = Thread.getCurrent(t);3073 _ = t;
3087 try current_thread.checkCancel();3074 try Thread.checkCancel();
30883075
3089 const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, sub_path);3076 const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, sub_path);
3090 const sub_path_w = sub_path_w_array.span();3077 const sub_path_w = sub_path_w_array.span();
...@@ -3143,7 +3130,7 @@ fn dirCreateFileWasi(...@@ -3143,7 +3130,7 @@ fn dirCreateFileWasi(
3143 flags: File.CreateFlags,3130 flags: File.CreateFlags,
3144) File.OpenError!File {3131) File.OpenError!File {
3145 const t: *Threaded = @ptrCast(@alignCast(userdata));3132 const t: *Threaded = @ptrCast(@alignCast(userdata));
3146 const current_thread = Thread.getCurrent(t);3133 _ = t;
3147 const wasi = std.os.wasi;3134 const wasi = std.os.wasi;
3148 const lookup_flags: wasi.lookupflags_t = .{};3135 const lookup_flags: wasi.lookupflags_t = .{};
3149 const oflags: wasi.oflags_t = .{3136 const oflags: wasi.oflags_t = .{
...@@ -3171,19 +3158,19 @@ fn dirCreateFileWasi(...@@ -3171,19 +3158,19 @@ fn dirCreateFileWasi(
3171 };3158 };
3172 const inheriting: wasi.rights_t = .{};3159 const inheriting: wasi.rights_t = .{};
3173 var fd: posix.fd_t = undefined;3160 var fd: posix.fd_t = undefined;
3174 try current_thread.beginSyscall();3161 const syscall: Syscall = try .start();
3175 while (true) {3162 while (true) {
3176 switch (wasi.path_open(dir.handle, lookup_flags, sub_path.ptr, sub_path.len, oflags, base, inheriting, fdflags, &fd)) {3163 switch (wasi.path_open(dir.handle, lookup_flags, sub_path.ptr, sub_path.len, oflags, base, inheriting, fdflags, &fd)) {
3177 .SUCCESS => {3164 .SUCCESS => {
3178 current_thread.endSyscall();3165 syscall.finish();
3179 return .{ .handle = fd };3166 return .{ .handle = fd };
3180 },3167 },
3181 .INTR => {3168 .INTR => {
3182 try current_thread.checkCancel();3169 try syscall.checkCancel();
3183 continue;3170 continue;
3184 },3171 },
3185 else => |e| {3172 else => |e| {
3186 current_thread.endSyscall();3173 syscall.finish();
3187 switch (e) {3174 switch (e) {
3188 .FAULT => |err| return errnoBug(err),3175 .FAULT => |err| return errnoBug(err),
3189 .INVAL => return error.BadPathName,3176 .INVAL => return error.BadPathName,
...@@ -3226,7 +3213,6 @@ fn dirOpenFilePosix(...@@ -3226,7 +3213,6 @@ fn dirOpenFilePosix(
3226 flags: File.OpenFlags,3213 flags: File.OpenFlags,
3227) File.OpenError!File {3214) File.OpenError!File {
3228 const t: *Threaded = @ptrCast(@alignCast(userdata));3215 const t: *Threaded = @ptrCast(@alignCast(userdata));
3229 const current_thread = Thread.getCurrent(t);
32303216
3231 var path_buffer: [posix.PATH_MAX]u8 = undefined;3217 var path_buffer: [posix.PATH_MAX]u8 = undefined;
3232 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);3218 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
...@@ -3266,133 +3252,137 @@ fn dirOpenFilePosix(...@@ -3266,133 +3252,137 @@ fn dirOpenFilePosix(
3266 },3252 },
3267 };3253 };
32683254
3269 try current_thread.beginSyscall();3255 const fd: posix.fd_t = fd: {
3270 const fd: posix.fd_t = while (true) {3256 const syscall: Syscall = try .start();
3271 const rc = openat_sym(dir.handle, sub_path_posix, os_flags, @as(posix.mode_t, 0));
3272 switch (posix.errno(rc)) {
3273 .SUCCESS => {
3274 current_thread.endSyscall();
3275 break @intCast(rc);
3276 },
3277 .INTR => {
3278 try current_thread.checkCancel();
3279 continue;
3280 },
3281 else => |e| {
3282 current_thread.endSyscall();
3283 switch (e) {
3284 .FAULT => |err| return errnoBug(err),
3285 .INVAL => return error.BadPathName,
3286 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
3287 .ACCES => return error.AccessDenied,
3288 .FBIG => return error.FileTooBig,
3289 .OVERFLOW => return error.FileTooBig,
3290 .ISDIR => return error.IsDir,
3291 .LOOP => return error.SymLinkLoop,
3292 .MFILE => return error.ProcessFdQuotaExceeded,
3293 .NAMETOOLONG => return error.NameTooLong,
3294 .NFILE => return error.SystemFdQuotaExceeded,
3295 .NODEV => return error.NoDevice,
3296 .NOENT => return error.FileNotFound,
3297 .SRCH => return error.FileNotFound, // Linux when opening procfs files.
3298 .NOMEM => return error.SystemResources,
3299 .NOSPC => return error.NoSpaceLeft,
3300 .NOTDIR => return error.NotDir,
3301 .PERM => return error.PermissionDenied,
3302 .EXIST => return error.PathAlreadyExists,
3303 .BUSY => return error.DeviceBusy,
3304 .OPNOTSUPP => return error.FileLocksUnsupported,
3305 .AGAIN => return error.WouldBlock,
3306 .TXTBSY => return error.FileBusy,
3307 .NXIO => return error.NoDevice,
3308 .ILSEQ => return error.BadPathName,
3309 else => |err| return posix.unexpectedErrno(err),
3310 }
3311 },
3312 }
3313 };
3314 errdefer posix.close(fd);
3315
3316 if (!flags.allow_directory) {
3317 const is_dir = is_dir: {
3318 const stat = fileStat(t, .{ .handle = fd }) catch |err| switch (err) {
3319 // The directory-ness is either unknown or unknowable
3320 error.Streaming => break :is_dir false,
3321 else => |e| return e,
3322 };
3323 break :is_dir stat.kind == .directory;
3324 };
3325 if (is_dir) return error.IsDir;
3326 }
3327
3328 if (have_flock and !have_flock_open_flags and flags.lock != .none) {
3329 const lock_nonblocking: i32 = if (flags.lock_nonblocking) posix.LOCK.NB else 0;
3330 const lock_flags = switch (flags.lock) {
3331 .none => unreachable,
3332 .shared => posix.LOCK.SH | lock_nonblocking,
3333 .exclusive => posix.LOCK.EX | lock_nonblocking,
3334 };
3335 try current_thread.beginSyscall();
3336 while (true) {3257 while (true) {
3337 switch (posix.errno(posix.system.flock(fd, lock_flags))) {3258 const rc = openat_sym(dir.handle, sub_path_posix, os_flags, @as(posix.mode_t, 0));
3259 switch (posix.errno(rc)) {
3338 .SUCCESS => {3260 .SUCCESS => {
3339 current_thread.endSyscall();3261 syscall.finish();
3340 break;3262 break :fd @intCast(rc);
3341 },3263 },
3342 .INTR => {3264 .INTR => {
3343 try current_thread.checkCancel();3265 try syscall.checkCancel();
3344 continue;3266 continue;
3345 },3267 },
3346 else => |e| {3268 else => |e| {
3347 current_thread.endSyscall();3269 syscall.finish();
3348 switch (e) {3270 switch (e) {
3271 .FAULT => |err| return errnoBug(err),
3272 .INVAL => return error.BadPathName,
3349 .BADF => |err| return errnoBug(err), // File descriptor used after closed.3273 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
3350 .INVAL => |err| return errnoBug(err), // invalid parameters3274 .ACCES => return error.AccessDenied,
3351 .NOLCK => return error.SystemResources,3275 .FBIG => return error.FileTooBig,
3352 .AGAIN => return error.WouldBlock,3276 .OVERFLOW => return error.FileTooBig,
3277 .ISDIR => return error.IsDir,
3278 .LOOP => return error.SymLinkLoop,
3279 .MFILE => return error.ProcessFdQuotaExceeded,
3280 .NAMETOOLONG => return error.NameTooLong,
3281 .NFILE => return error.SystemFdQuotaExceeded,
3282 .NODEV => return error.NoDevice,
3283 .NOENT => return error.FileNotFound,
3284 .SRCH => return error.FileNotFound, // Linux when opening procfs files.
3285 .NOMEM => return error.SystemResources,
3286 .NOSPC => return error.NoSpaceLeft,
3287 .NOTDIR => return error.NotDir,
3288 .PERM => return error.PermissionDenied,
3289 .EXIST => return error.PathAlreadyExists,
3290 .BUSY => return error.DeviceBusy,
3353 .OPNOTSUPP => return error.FileLocksUnsupported,3291 .OPNOTSUPP => return error.FileLocksUnsupported,
3292 .AGAIN => return error.WouldBlock,
3293 .TXTBSY => return error.FileBusy,
3294 .NXIO => return error.NoDevice,
3295 .ILSEQ => return error.BadPathName,
3354 else => |err| return posix.unexpectedErrno(err),3296 else => |err| return posix.unexpectedErrno(err),
3355 }3297 }
3356 },3298 },
3357 }3299 }
3358 }3300 }
3301 };
3302 errdefer posix.close(fd);
3303
3304 if (!flags.allow_directory) {
3305 const is_dir = is_dir: {
3306 const stat = fileStat(t, .{ .handle = fd }) catch |err| switch (err) {
3307 // The directory-ness is either unknown or unknowable
3308 error.Streaming => break :is_dir false,
3309 else => |e| return e,
3310 };
3311 break :is_dir stat.kind == .directory;
3312 };
3313 if (is_dir) return error.IsDir;
3359 }3314 }
33603315
3361 if (have_flock_open_flags and flags.lock_nonblocking) {3316 if (have_flock and !have_flock_open_flags and flags.lock != .none) {
3362 try current_thread.beginSyscall();3317 const lock_nonblocking: i32 = if (flags.lock_nonblocking) posix.LOCK.NB else 0;
3363 var fl_flags: usize = while (true) {3318 const lock_flags = switch (flags.lock) {
3364 const rc = posix.system.fcntl(fd, posix.F.GETFL, @as(usize, 0));3319 .none => unreachable,
3365 switch (posix.errno(rc)) {3320 .shared => posix.LOCK.SH | lock_nonblocking,
3321 .exclusive => posix.LOCK.EX | lock_nonblocking,
3322 };
3323 const syscall: Syscall = try .start();
3324 while (true) {
3325 switch (posix.errno(posix.system.flock(fd, lock_flags))) {
3366 .SUCCESS => {3326 .SUCCESS => {
3367 current_thread.endSyscall();3327 syscall.finish();
3368 break @intCast(rc);3328 break;
3369 },3329 },
3370 .INTR => {3330 .INTR => {
3371 try current_thread.checkCancel();3331 try syscall.checkCancel();
3372 continue;3332 continue;
3373 },3333 },
3374 else => |err| {3334 else => |e| {
3375 current_thread.endSyscall();3335 syscall.finish();
3376 return posix.unexpectedErrno(err);3336 switch (e) {
3337 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
3338 .INVAL => |err| return errnoBug(err), // invalid parameters
3339 .NOLCK => return error.SystemResources,
3340 .AGAIN => return error.WouldBlock,
3341 .OPNOTSUPP => return error.FileLocksUnsupported,
3342 else => |err| return posix.unexpectedErrno(err),
3343 }
3377 },3344 },
3378 }3345 }
3346 }
3347 }
3348
3349 if (have_flock_open_flags and flags.lock_nonblocking) {
3350 var fl_flags: usize = fl: {
3351 const syscall: Syscall = try .start();
3352 while (true) {
3353 const rc = posix.system.fcntl(fd, posix.F.GETFL, @as(usize, 0));
3354 switch (posix.errno(rc)) {
3355 .SUCCESS => {
3356 syscall.finish();
3357 break :fl @intCast(rc);
3358 },
3359 .INTR => {
3360 try syscall.checkCancel();
3361 continue;
3362 },
3363 else => |err| {
3364 syscall.finish();
3365 return posix.unexpectedErrno(err);
3366 },
3367 }
3368 }
3379 };3369 };
33803370
3381 fl_flags |= @as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK"));3371 fl_flags |= @as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK"));
33823372
3383 try current_thread.beginSyscall();3373 const syscall: Syscall = try .start();
3384 while (true) {3374 while (true) {
3385 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFL, fl_flags))) {3375 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFL, fl_flags))) {
3386 .SUCCESS => {3376 .SUCCESS => {
3387 current_thread.endSyscall();3377 syscall.finish();
3388 break;3378 break;
3389 },3379 },
3390 .INTR => {3380 .INTR => {
3391 try current_thread.checkCancel();3381 try syscall.checkCancel();
3392 continue;3382 continue;
3393 },3383 },
3394 else => |err| {3384 else => |err| {
3395 current_thread.endSyscall();3385 syscall.finish();
3396 return posix.unexpectedErrno(err);3386 return posix.unexpectedErrno(err);
3397 },3387 },
3398 }3388 }
...@@ -3425,7 +3415,7 @@ pub fn dirOpenFileWtf16(...@@ -3425,7 +3415,7 @@ pub fn dirOpenFileWtf16(
3425 if (!allow_directory and std.mem.eql(u16, sub_path_w, &.{'.'})) return error.IsDir;3415 if (!allow_directory and std.mem.eql(u16, sub_path_w, &.{'.'})) return error.IsDir;
3426 if (!allow_directory and std.mem.eql(u16, sub_path_w, &.{ '.', '.' })) return error.IsDir;3416 if (!allow_directory and std.mem.eql(u16, sub_path_w, &.{ '.', '.' })) return error.IsDir;
3427 const path_len_bytes = std.math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong;3417 const path_len_bytes = std.math.cast(u16, sub_path_w.len * 2) orelse return error.NameTooLong;
3428 const current_thread = Thread.getCurrent(t);3418 _ = t;
3429 const w = windows;3419 const w = windows;
34303420
3431 var nt_name: w.UNICODE_STRING = .{3421 var nt_name: w.UNICODE_STRING = .{
...@@ -3448,7 +3438,7 @@ pub fn dirOpenFileWtf16(...@@ -3448,7 +3438,7 @@ pub fn dirOpenFileWtf16(
3448 var attempt: u5 = 0;3438 var attempt: u5 = 0;
34493439
3450 const handle = while (true) {3440 const handle = while (true) {
3451 try current_thread.checkCancel();3441 try Thread.checkCancel();
34523442
3453 var result: w.HANDLE = undefined;3443 var result: w.HANDLE = undefined;
3454 const rc = w.ntdll.NtCreateFile(3444 const rc = w.ntdll.NtCreateFile(
...@@ -3555,7 +3545,6 @@ fn dirOpenFileWasi(...@@ -3555,7 +3545,6 @@ fn dirOpenFileWasi(
3555) File.OpenError!File {3545) File.OpenError!File {
3556 if (builtin.link_libc) return dirOpenFilePosix(userdata, dir, sub_path, flags);3546 if (builtin.link_libc) return dirOpenFilePosix(userdata, dir, sub_path, flags);
3557 const t: *Threaded = @ptrCast(@alignCast(userdata));3547 const t: *Threaded = @ptrCast(@alignCast(userdata));
3558 const current_thread = Thread.getCurrent(t);
3559 const wasi = std.os.wasi;3548 const wasi = std.os.wasi;
3560 var base: std.os.wasi.rights_t = .{};3549 var base: std.os.wasi.rights_t = .{};
3561 // POLL_FD_READWRITE only grants extra rights if the corresponding FD_READ and/or FD_WRITE3550 // POLL_FD_READWRITE only grants extra rights if the corresponding FD_READ and/or FD_WRITE
...@@ -3585,19 +3574,19 @@ fn dirOpenFileWasi(...@@ -3585,19 +3574,19 @@ fn dirOpenFileWasi(
3585 const inheriting: wasi.rights_t = .{};3574 const inheriting: wasi.rights_t = .{};
3586 const fdflags: wasi.fdflags_t = .{};3575 const fdflags: wasi.fdflags_t = .{};
3587 var fd: posix.fd_t = undefined;3576 var fd: posix.fd_t = undefined;
3588 try current_thread.beginSyscall();3577 const syscall: Syscall = try .start();
3589 while (true) {3578 while (true) {
3590 switch (wasi.path_open(dir.handle, lookup_flags, sub_path.ptr, sub_path.len, oflags, base, inheriting, fdflags, &fd)) {3579 switch (wasi.path_open(dir.handle, lookup_flags, sub_path.ptr, sub_path.len, oflags, base, inheriting, fdflags, &fd)) {
3591 .SUCCESS => {3580 .SUCCESS => {
3592 current_thread.endSyscall();3581 syscall.finish();
3593 break;3582 break;
3594 },3583 },
3595 .INTR => {3584 .INTR => {
3596 try current_thread.checkCancel();3585 try syscall.checkCancel();
3597 continue;3586 continue;
3598 },3587 },
3599 else => |e| {3588 else => |e| {
3600 current_thread.endSyscall();3589 syscall.finish();
3601 switch (e) {3590 switch (e) {
3602 .FAULT => |err| return errnoBug(err),3591 .FAULT => |err| return errnoBug(err),
3603 .BADF => |err| return errnoBug(err), // File descriptor used after closed.3592 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -3654,14 +3643,13 @@ fn dirOpenDirPosix(...@@ -3654,14 +3643,13 @@ fn dirOpenDirPosix(
3654 options: Dir.OpenOptions,3643 options: Dir.OpenOptions,
3655) Dir.OpenError!Dir {3644) Dir.OpenError!Dir {
3656 const t: *Threaded = @ptrCast(@alignCast(userdata));3645 const t: *Threaded = @ptrCast(@alignCast(userdata));
3646 _ = t;
36573647
3658 if (is_windows) {3648 if (is_windows) {
3659 const sub_path_w = try windows.sliceToPrefixedFileW(dir.handle, sub_path);3649 const sub_path_w = try windows.sliceToPrefixedFileW(dir.handle, sub_path);
3660 return dirOpenDirWindows(t, dir, sub_path_w.span(), options);3650 return dirOpenDirWindows(dir, sub_path_w.span(), options);
3661 }3651 }
36623652
3663 const current_thread = Thread.getCurrent(t);
3664
3665 var path_buffer: [posix.PATH_MAX]u8 = undefined;3653 var path_buffer: [posix.PATH_MAX]u8 = undefined;
3666 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);3654 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
36673655
...@@ -3682,20 +3670,20 @@ fn dirOpenDirPosix(...@@ -3682,20 +3670,20 @@ fn dirOpenDirPosix(
3682 if (@hasField(posix.O, "PATH") and !options.iterate)3670 if (@hasField(posix.O, "PATH") and !options.iterate)
3683 flags.PATH = true;3671 flags.PATH = true;
36843672
3685 try current_thread.beginSyscall();3673 const syscall: Syscall = try .start();
3686 while (true) {3674 while (true) {
3687 const rc = openat_sym(dir.handle, sub_path_posix, flags, @as(usize, 0));3675 const rc = openat_sym(dir.handle, sub_path_posix, flags, @as(usize, 0));
3688 switch (posix.errno(rc)) {3676 switch (posix.errno(rc)) {
3689 .SUCCESS => {3677 .SUCCESS => {
3690 current_thread.endSyscall();3678 syscall.finish();
3691 return .{ .handle = @intCast(rc) };3679 return .{ .handle = @intCast(rc) };
3692 },3680 },
3693 .INTR => {3681 .INTR => {
3694 try current_thread.checkCancel();3682 try syscall.checkCancel();
3695 continue;3683 continue;
3696 },3684 },
3697 else => |e| {3685 else => |e| {
3698 current_thread.endSyscall();3686 syscall.finish();
3699 switch (e) {3687 switch (e) {
3700 .FAULT => |err| return errnoBug(err),3688 .FAULT => |err| return errnoBug(err),
3701 .INVAL => return error.BadPathName,3689 .INVAL => return error.BadPathName,
...@@ -3727,27 +3715,27 @@ fn dirOpenDirHaiku(...@@ -3727,27 +3715,27 @@ fn dirOpenDirHaiku(
3727 options: Dir.OpenOptions,3715 options: Dir.OpenOptions,
3728) Dir.OpenError!Dir {3716) Dir.OpenError!Dir {
3729 const t: *Threaded = @ptrCast(@alignCast(userdata));3717 const t: *Threaded = @ptrCast(@alignCast(userdata));
3730 const current_thread = Thread.getCurrent(t);3718 _ = t;
37313719
3732 var path_buffer: [posix.PATH_MAX]u8 = undefined;3720 var path_buffer: [posix.PATH_MAX]u8 = undefined;
3733 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);3721 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
37343722
3735 _ = options;3723 _ = options;
37363724
3737 try current_thread.beginSyscall();3725 const syscall: Syscall = try .start();
3738 while (true) {3726 while (true) {
3739 const rc = posix.system._kern_open_dir(dir.handle, sub_path_posix);3727 const rc = posix.system._kern_open_dir(dir.handle, sub_path_posix);
3740 if (rc >= 0) {3728 if (rc >= 0) {
3741 current_thread.endSyscall();3729 syscall.finish();
3742 return .{ .handle = rc };3730 return .{ .handle = rc };
3743 }3731 }
3744 switch (@as(posix.E, @enumFromInt(rc))) {3732 switch (@as(posix.E, @enumFromInt(rc))) {
3745 .INTR => {3733 .INTR => {
3746 try current_thread.checkCancel();3734 try syscall.checkCancel();
3747 continue;3735 continue;
3748 },3736 },
3749 else => |e| {3737 else => |e| {
3750 current_thread.endSyscall();3738 syscall.finish();
3751 switch (e) {3739 switch (e) {
3752 .FAULT => |err| return errnoBug(err),3740 .FAULT => |err| return errnoBug(err),
3753 .INVAL => |err| return errnoBug(err),3741 .INVAL => |err| return errnoBug(err),
...@@ -3771,12 +3759,10 @@ fn dirOpenDirHaiku(...@@ -3771,12 +3759,10 @@ fn dirOpenDirHaiku(
3771}3759}
37723760
3773pub fn dirOpenDirWindows(3761pub fn dirOpenDirWindows(
3774 t: *Io.Threaded,
3775 dir: Dir,3762 dir: Dir,
3776 sub_path_w: [:0]const u16,3763 sub_path_w: [:0]const u16,
3777 options: Dir.OpenOptions,3764 options: Dir.OpenOptions,
3778) Dir.OpenError!Dir {3765) Dir.OpenError!Dir {
3779 const current_thread = Thread.getCurrent(t);
3780 const w = windows;3766 const w = windows;
37813767
3782 const path_len_bytes: u16 = @intCast(sub_path_w.len * 2);3768 const path_len_bytes: u16 = @intCast(sub_path_w.len * 2);
...@@ -3787,7 +3773,7 @@ pub fn dirOpenDirWindows(...@@ -3787,7 +3773,7 @@ pub fn dirOpenDirWindows(
3787 };3773 };
3788 var io_status_block: w.IO_STATUS_BLOCK = undefined;3774 var io_status_block: w.IO_STATUS_BLOCK = undefined;
3789 var result: Dir = .{ .handle = undefined };3775 var result: Dir = .{ .handle = undefined };
3790 try current_thread.checkCancel();3776 try Thread.checkCancel();
3791 const rc = w.ntdll.NtCreateFile(3777 const rc = w.ntdll.NtCreateFile(
3792 &result.handle,3778 &result.handle,
3793 // TODO remove some of these flags if options.access_sub_paths is false3779 // TODO remove some of these flags if options.access_sub_paths is false
...@@ -3861,7 +3847,7 @@ const dirRead = switch (native_os) {...@@ -3861,7 +3847,7 @@ const dirRead = switch (native_os) {
3861fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {3847fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
3862 const linux = std.os.linux;3848 const linux = std.os.linux;
3863 const t: *Threaded = @ptrCast(@alignCast(userdata));3849 const t: *Threaded = @ptrCast(@alignCast(userdata));
3864 const current_thread = Thread.getCurrent(t);3850 _ = t;
3865 var buffer_index: usize = 0;3851 var buffer_index: usize = 0;
3866 while (buffer.len - buffer_index != 0) {3852 while (buffer.len - buffer_index != 0) {
3867 if (dr.end - dr.index == 0) {3853 if (dr.end - dr.index == 0) {
...@@ -3869,26 +3855,26 @@ fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir...@@ -3869,26 +3855,26 @@ fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir
3869 // buffered data.3855 // buffered data.
3870 if (buffer_index != 0) break;3856 if (buffer_index != 0) break;
3871 if (dr.state == .reset) {3857 if (dr.state == .reset) {
3872 posixSeekTo(current_thread, dr.dir.handle, 0) catch |err| switch (err) {3858 posixSeekTo(dr.dir.handle, 0) catch |err| switch (err) {
3873 error.Unseekable => return error.Unexpected,3859 error.Unseekable => return error.Unexpected,
3874 else => |e| return e,3860 else => |e| return e,
3875 };3861 };
3876 dr.state = .reading;3862 dr.state = .reading;
3877 }3863 }
3878 try current_thread.beginSyscall();3864 const syscall: Syscall = try .start();
3879 const n = while (true) {3865 const n = while (true) {
3880 const rc = linux.getdents64(dr.dir.handle, dr.buffer.ptr, dr.buffer.len);3866 const rc = linux.getdents64(dr.dir.handle, dr.buffer.ptr, dr.buffer.len);
3881 switch (linux.errno(rc)) {3867 switch (linux.errno(rc)) {
3882 .SUCCESS => {3868 .SUCCESS => {
3883 current_thread.endSyscall();3869 syscall.finish();
3884 break rc;3870 break rc;
3885 },3871 },
3886 .INTR => {3872 .INTR => {
3887 try current_thread.checkCancel();3873 try syscall.checkCancel();
3888 continue;3874 continue;
3889 },3875 },
3890 else => |e| {3876 else => |e| {
3891 current_thread.endSyscall();3877 syscall.finish();
3892 switch (e) {3878 switch (e) {
3893 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability.3879 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability.
3894 .FAULT => |err| return errnoBug(err),3880 .FAULT => |err| return errnoBug(err),
...@@ -3958,7 +3944,7 @@ fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir...@@ -3958,7 +3944,7 @@ fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir
39583944
3959fn dirReadDarwin(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {3945fn dirReadDarwin(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
3960 const t: *Threaded = @ptrCast(@alignCast(userdata));3946 const t: *Threaded = @ptrCast(@alignCast(userdata));
3961 const current_thread = Thread.getCurrent(t);3947 _ = t;
3962 const Header = extern struct {3948 const Header = extern struct {
3963 seek: i64,3949 seek: i64,
3964 };3950 };
...@@ -3977,27 +3963,27 @@ fn dirReadDarwin(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Di...@@ -3977,27 +3963,27 @@ fn dirReadDarwin(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Di
3977 // buffered data.3963 // buffered data.
3978 if (buffer_index != 0) break;3964 if (buffer_index != 0) break;
3979 if (dr.state == .reset) {3965 if (dr.state == .reset) {
3980 posixSeekTo(current_thread, dr.dir.handle, 0) catch |err| switch (err) {3966 posixSeekTo(dr.dir.handle, 0) catch |err| switch (err) {
3981 error.Unseekable => return error.Unexpected,3967 error.Unseekable => return error.Unexpected,
3982 else => |e| return e,3968 else => |e| return e,
3983 };3969 };
3984 dr.state = .reading;3970 dr.state = .reading;
3985 }3971 }
3986 const dents_buffer = dr.buffer[header_end..];3972 const dents_buffer = dr.buffer[header_end..];
3987 try current_thread.beginSyscall();3973 const syscall: Syscall = try .start();
3988 const n: usize = while (true) {3974 const n: usize = while (true) {
3989 const rc = posix.system.getdirentries(dr.dir.handle, dents_buffer.ptr, dents_buffer.len, &header.seek);3975 const rc = posix.system.getdirentries(dr.dir.handle, dents_buffer.ptr, dents_buffer.len, &header.seek);
3990 switch (posix.errno(rc)) {3976 switch (posix.errno(rc)) {
3991 .SUCCESS => {3977 .SUCCESS => {
3992 current_thread.endSyscall();3978 syscall.finish();
3993 break @intCast(rc);3979 break @intCast(rc);
3994 },3980 },
3995 .INTR => {3981 .INTR => {
3996 try current_thread.checkCancel();3982 try syscall.checkCancel();
3997 continue;3983 continue;
3998 },3984 },
3999 else => |e| {3985 else => |e| {
4000 current_thread.endSyscall();3986 syscall.finish();
4001 switch (e) {3987 switch (e) {
4002 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability.3988 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability.
4003 .FAULT => |err| return errnoBug(err),3989 .FAULT => |err| return errnoBug(err),
...@@ -4046,7 +4032,7 @@ fn dirReadDarwin(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Di...@@ -4046,7 +4032,7 @@ fn dirReadDarwin(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Di
40464032
4047fn dirReadBsd(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {4033fn dirReadBsd(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
4048 const t: *Threaded = @ptrCast(@alignCast(userdata));4034 const t: *Threaded = @ptrCast(@alignCast(userdata));
4049 const current_thread = Thread.getCurrent(t);4035 _ = t;
4050 var buffer_index: usize = 0;4036 var buffer_index: usize = 0;
4051 while (buffer.len - buffer_index != 0) {4037 while (buffer.len - buffer_index != 0) {
4052 if (dr.end - dr.index == 0) {4038 if (dr.end - dr.index == 0) {
...@@ -4054,26 +4040,26 @@ fn dirReadBsd(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.R...@@ -4054,26 +4040,26 @@ fn dirReadBsd(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.R
4054 // buffered data.4040 // buffered data.
4055 if (buffer_index != 0) break;4041 if (buffer_index != 0) break;
4056 if (dr.state == .reset) {4042 if (dr.state == .reset) {
4057 posixSeekTo(current_thread, dr.dir.handle, 0) catch |err| switch (err) {4043 posixSeekTo(dr.dir.handle, 0) catch |err| switch (err) {
4058 error.Unseekable => return error.Unexpected,4044 error.Unseekable => return error.Unexpected,
4059 else => |e| return e,4045 else => |e| return e,
4060 };4046 };
4061 dr.state = .reading;4047 dr.state = .reading;
4062 }4048 }
4063 try current_thread.beginSyscall();4049 const syscall: Syscall = try .start();
4064 const n: usize = while (true) {4050 const n: usize = while (true) {
4065 const rc = posix.system.getdents(dr.dir.handle, dr.buffer.ptr, dr.buffer.len);4051 const rc = posix.system.getdents(dr.dir.handle, dr.buffer.ptr, dr.buffer.len);
4066 switch (posix.errno(rc)) {4052 switch (posix.errno(rc)) {
4067 .SUCCESS => {4053 .SUCCESS => {
4068 current_thread.endSyscall();4054 syscall.finish();
4069 break @intCast(rc);4055 break @intCast(rc);
4070 },4056 },
4071 .INTR => {4057 .INTR => {
4072 try current_thread.checkCancel();4058 try syscall.checkCancel();
4073 continue;4059 continue;
4074 },4060 },
4075 else => |e| {4061 else => |e| {
4076 current_thread.endSyscall();4062 syscall.finish();
4077 switch (e) {4063 switch (e) {
4078 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability4064 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability
4079 .FAULT => |err| return errnoBug(err),4065 .FAULT => |err| return errnoBug(err),
...@@ -4140,7 +4126,7 @@ fn dirReadBsd(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.R...@@ -4140,7 +4126,7 @@ fn dirReadBsd(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.R
41404126
4141fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {4127fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
4142 const t: *Threaded = @ptrCast(@alignCast(userdata));4128 const t: *Threaded = @ptrCast(@alignCast(userdata));
4143 const current_thread = Thread.getCurrent(t);4129 _ = t;
4144 var buffer_index: usize = 0;4130 var buffer_index: usize = 0;
4145 while (buffer.len - buffer_index != 0) {4131 while (buffer.len - buffer_index != 0) {
4146 if (dr.end - dr.index == 0) {4132 if (dr.end - dr.index == 0) {
...@@ -4148,26 +4134,26 @@ fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) D...@@ -4148,26 +4134,26 @@ fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) D
4148 // buffered data.4134 // buffered data.
4149 if (buffer_index != 0) break;4135 if (buffer_index != 0) break;
4150 if (dr.state == .reset) {4136 if (dr.state == .reset) {
4151 posixSeekTo(current_thread, dr.dir.handle, 0) catch |err| switch (err) {4137 posixSeekTo(dr.dir.handle, 0) catch |err| switch (err) {
4152 error.Unseekable => return error.Unexpected,4138 error.Unseekable => return error.Unexpected,
4153 else => |e| return e,4139 else => |e| return e,
4154 };4140 };
4155 dr.state = .reading;4141 dr.state = .reading;
4156 }4142 }
4157 try current_thread.beginSyscall();4143 const syscall: Syscall = try .start();
4158 const n: usize = while (true) {4144 const n: usize = while (true) {
4159 const rc = posix.system.getdents(dr.dir.handle, dr.buffer.ptr, dr.buffer.len);4145 const rc = posix.system.getdents(dr.dir.handle, dr.buffer.ptr, dr.buffer.len);
4160 switch (posix.errno(rc)) {4146 switch (posix.errno(rc)) {
4161 .SUCCESS => {4147 .SUCCESS => {
4162 current_thread.endSyscall();4148 syscall.finish();
4163 break rc;4149 break rc;
4164 },4150 },
4165 .INTR => {4151 .INTR => {
4166 try current_thread.checkCancel();4152 try syscall.checkCancel();
4167 continue;4153 continue;
4168 },4154 },
4169 else => |e| {4155 else => |e| {
4170 current_thread.endSyscall();4156 syscall.finish();
4171 switch (e) {4157 switch (e) {
4172 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability4158 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability
4173 .FAULT => |err| return errnoBug(err),4159 .FAULT => |err| return errnoBug(err),
...@@ -4193,7 +4179,7 @@ fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) D...@@ -4193,7 +4179,7 @@ fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) D
4193 if (std.mem.eql(u8, name, ".") or std.mem.eql(u8, name, "..")) continue;4179 if (std.mem.eql(u8, name, ".") or std.mem.eql(u8, name, "..")) continue;
41944180
4195 // illumos dirent doesn't expose type, so we have to call stat to get it.4181 // illumos dirent doesn't expose type, so we have to call stat to get it.
4196 const stat = try posixStatFile(current_thread, dr.dir.handle, name, posix.AT.SYMLINK_NOFOLLOW);4182 const stat = try posixStatFile(dr.dir.handle, name, posix.AT.SYMLINK_NOFOLLOW);
41974183
4198 buffer[buffer_index] = .{4184 buffer[buffer_index] = .{
4199 .name = name,4185 .name = name,
...@@ -4214,7 +4200,7 @@ fn dirReadHaiku(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir...@@ -4214,7 +4200,7 @@ fn dirReadHaiku(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir
42144200
4215fn dirReadWindows(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {4201fn dirReadWindows(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
4216 const t: *Threaded = @ptrCast(@alignCast(userdata));4202 const t: *Threaded = @ptrCast(@alignCast(userdata));
4217 const current_thread = Thread.getCurrent(t);4203 _ = t;
4218 const w = windows;4204 const w = windows;
42194205
4220 // We want to be able to use the `dr.buffer` for both the NtQueryDirectoryFile call (which4206 // We want to be able to use the `dr.buffer` for both the NtQueryDirectoryFile call (which
...@@ -4278,7 +4264,7 @@ fn dirReadWindows(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) D...@@ -4278,7 +4264,7 @@ fn dirReadWindows(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) D
4278 // buffered data.4264 // buffered data.
4279 if (buffer_index != 0) break;4265 if (buffer_index != 0) break;
42804266
4281 try current_thread.checkCancel();4267 try Thread.checkCancel();
4282 var io_status_block: w.IO_STATUS_BLOCK = undefined;4268 var io_status_block: w.IO_STATUS_BLOCK = undefined;
4283 const rc = w.ntdll.NtQueryDirectoryFile(4269 const rc = w.ntdll.NtQueryDirectoryFile(
4284 dr.dir.handle,4270 dr.dir.handle,
...@@ -4364,7 +4350,7 @@ fn dirReadWasi(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir....@@ -4364,7 +4350,7 @@ fn dirReadWasi(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.
4364 // complexity here.4350 // complexity here.
4365 const wasi = std.os.wasi;4351 const wasi = std.os.wasi;
4366 const t: *Threaded = @ptrCast(@alignCast(userdata));4352 const t: *Threaded = @ptrCast(@alignCast(userdata));
4367 const current_thread = Thread.getCurrent(t);4353 _ = t;
4368 const Header = extern struct {4354 const Header = extern struct {
4369 cookie: u64,4355 cookie: u64,
4370 };4356 };
...@@ -4390,19 +4376,19 @@ fn dirReadWasi(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir....@@ -4390,19 +4376,19 @@ fn dirReadWasi(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.
4390 }4376 }
4391 const dents_buffer = dr.buffer[header_end..];4377 const dents_buffer = dr.buffer[header_end..];
4392 var n: usize = undefined;4378 var n: usize = undefined;
4393 try current_thread.beginSyscall();4379 const syscall: Syscall = try .start();
4394 while (true) {4380 while (true) {
4395 switch (wasi.fd_readdir(dr.dir.handle, dents_buffer.ptr, dents_buffer.len, header.cookie, &n)) {4381 switch (wasi.fd_readdir(dr.dir.handle, dents_buffer.ptr, dents_buffer.len, header.cookie, &n)) {
4396 .SUCCESS => {4382 .SUCCESS => {
4397 current_thread.endSyscall();4383 syscall.finish();
4398 break;4384 break;
4399 },4385 },
4400 .INTR => {4386 .INTR => {
4401 try current_thread.checkCancel();4387 try syscall.checkCancel();
4402 continue;4388 continue;
4403 },4389 },
4404 else => |e| {4390 else => |e| {
4405 current_thread.endSyscall();4391 syscall.finish();
4406 switch (e) {4392 switch (e) {
4407 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability.4393 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability.
4408 .FAULT => |err| return errnoBug(err),4394 .FAULT => |err| return errnoBug(err),
...@@ -4478,9 +4464,9 @@ const dirRealPathFile = switch (native_os) {...@@ -4478,9 +4464,9 @@ const dirRealPathFile = switch (native_os) {
44784464
4479fn dirRealPathFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_buffer: []u8) Dir.RealPathFileError!usize {4465fn dirRealPathFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_buffer: []u8) Dir.RealPathFileError!usize {
4480 const t: *Threaded = @ptrCast(@alignCast(userdata));4466 const t: *Threaded = @ptrCast(@alignCast(userdata));
4481 const current_thread = Thread.getCurrent(t);4467 _ = t;
44824468
4483 try current_thread.checkCancel();4469 try Thread.checkCancel();
44844470
4485 var path_name_w = try windows.sliceToPrefixedFileW(dir.handle, sub_path);4471 var path_name_w = try windows.sliceToPrefixedFileW(dir.handle, sub_path);
44864472
...@@ -4500,11 +4486,11 @@ fn dirRealPathFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8,...@@ -4500,11 +4486,11 @@ fn dirRealPathFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8,
4500 break :blk res;4486 break :blk res;
4501 };4487 };
4502 defer windows.CloseHandle(h_file);4488 defer windows.CloseHandle(h_file);
4503 return realPathWindows(current_thread, h_file, out_buffer);4489 return realPathWindows(h_file, out_buffer);
4504}4490}
45054491
4506fn realPathWindows(current_thread: *Thread, h_file: windows.HANDLE, out_buffer: []u8) File.RealPathError!usize {4492fn realPathWindows(h_file: windows.HANDLE, out_buffer: []u8) File.RealPathError!usize {
4507 _ = current_thread; // TODO move GetFinalPathNameByHandle logic into std.Io.Threaded and add cancel checks4493 // TODO move GetFinalPathNameByHandle logic into std.Io.Threaded and add cancel checks
4508 var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined;4494 var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined;
4509 const wide_slice = try windows.GetFinalPathNameByHandle(h_file, .{}, &wide_buf);4495 const wide_slice = try windows.GetFinalPathNameByHandle(h_file, .{}, &wide_buf);
45104496
...@@ -4519,26 +4505,26 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o...@@ -4519,26 +4505,26 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o
4519 if (native_os == .wasi) return error.OperationUnsupported;4505 if (native_os == .wasi) return error.OperationUnsupported;
45204506
4521 const t: *Threaded = @ptrCast(@alignCast(userdata));4507 const t: *Threaded = @ptrCast(@alignCast(userdata));
4522 const current_thread = Thread.getCurrent(t);4508 _ = t;
45234509
4524 var path_buffer: [posix.PATH_MAX]u8 = undefined;4510 var path_buffer: [posix.PATH_MAX]u8 = undefined;
4525 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);4511 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
45264512
4527 if (builtin.link_libc and dir.handle == posix.AT.FDCWD) {4513 if (builtin.link_libc and dir.handle == posix.AT.FDCWD) {
4528 if (out_buffer.len < posix.PATH_MAX) return error.NameTooLong;4514 if (out_buffer.len < posix.PATH_MAX) return error.NameTooLong;
4529 try current_thread.beginSyscall();4515 const syscall: Syscall = try .start();
4530 while (true) {4516 while (true) {
4531 if (std.c.realpath(sub_path_posix, out_buffer.ptr)) |redundant_pointer| {4517 if (std.c.realpath(sub_path_posix, out_buffer.ptr)) |redundant_pointer| {
4532 current_thread.endSyscall();4518 syscall.finish();
4533 assert(redundant_pointer == out_buffer.ptr);4519 assert(redundant_pointer == out_buffer.ptr);
4534 return std.mem.indexOfScalar(u8, out_buffer, 0) orelse out_buffer.len;4520 return std.mem.indexOfScalar(u8, out_buffer, 0) orelse out_buffer.len;
4535 }4521 }
4536 const err: posix.E = @enumFromInt(std.c._errno().*);4522 const err: posix.E = @enumFromInt(std.c._errno().*);
4537 if (err == .INTR) {4523 if (err == .INTR) {
4538 try current_thread.checkCancel();4524 try syscall.checkCancel();
4539 continue;4525 continue;
4540 }4526 }
4541 current_thread.endSyscall();4527 syscall.finish();
4542 switch (err) {4528 switch (err) {
4543 .INVAL => return errnoBug(err),4529 .INVAL => return errnoBug(err),
4544 .BADF => return errnoBug(err),4530 .BADF => return errnoBug(err),
...@@ -4562,20 +4548,20 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o...@@ -4562,20 +4548,20 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o
45624548
4563 const mode: posix.mode_t = 0;4549 const mode: posix.mode_t = 0;
45644550
4565 try current_thread.beginSyscall();4551 const syscall: Syscall = try .start();
4566 const fd: posix.fd_t = while (true) {4552 const fd: posix.fd_t = while (true) {
4567 const rc = openat_sym(dir.handle, sub_path_posix, flags, mode);4553 const rc = openat_sym(dir.handle, sub_path_posix, flags, mode);
4568 switch (posix.errno(rc)) {4554 switch (posix.errno(rc)) {
4569 .SUCCESS => {4555 .SUCCESS => {
4570 current_thread.endSyscall();4556 syscall.finish();
4571 break @intCast(rc);4557 break @intCast(rc);
4572 },4558 },
4573 .INTR => {4559 .INTR => {
4574 try current_thread.checkCancel();4560 try syscall.checkCancel();
4575 continue;4561 continue;
4576 },4562 },
4577 else => |e| {4563 else => |e| {
4578 current_thread.endSyscall();4564 syscall.finish();
4579 switch (e) {4565 switch (e) {
4580 .FAULT => |err| return errnoBug(err),4566 .FAULT => |err| return errnoBug(err),
4581 .INVAL => return error.BadPathName,4567 .INVAL => return error.BadPathName,
...@@ -4605,7 +4591,7 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o...@@ -4605,7 +4591,7 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o
4605 }4591 }
4606 };4592 };
4607 defer posix.close(fd);4593 defer posix.close(fd);
4608 return realPathPosix(current_thread, fd, out_buffer);4594 return realPathPosix(fd, out_buffer);
4609}4595}
46104596
4611const dirRealPath = switch (native_os) {4597const dirRealPath = switch (native_os) {
...@@ -4616,14 +4602,14 @@ const dirRealPath = switch (native_os) {...@@ -4616,14 +4602,14 @@ const dirRealPath = switch (native_os) {
4616fn dirRealPathPosix(userdata: ?*anyopaque, dir: Dir, out_buffer: []u8) Dir.RealPathError!usize {4602fn dirRealPathPosix(userdata: ?*anyopaque, dir: Dir, out_buffer: []u8) Dir.RealPathError!usize {
4617 if (native_os == .wasi) return error.OperationUnsupported;4603 if (native_os == .wasi) return error.OperationUnsupported;
4618 const t: *Threaded = @ptrCast(@alignCast(userdata));4604 const t: *Threaded = @ptrCast(@alignCast(userdata));
4619 const current_thread = Thread.getCurrent(t);4605 _ = t;
4620 return realPathPosix(current_thread, dir.handle, out_buffer);4606 return realPathPosix(dir.handle, out_buffer);
4621}4607}
46224608
4623fn dirRealPathWindows(userdata: ?*anyopaque, dir: Dir, out_buffer: []u8) Dir.RealPathError!usize {4609fn dirRealPathWindows(userdata: ?*anyopaque, dir: Dir, out_buffer: []u8) Dir.RealPathError!usize {
4624 const t: *Threaded = @ptrCast(@alignCast(userdata));4610 const t: *Threaded = @ptrCast(@alignCast(userdata));
4625 const current_thread = Thread.getCurrent(t);4611 _ = t;
4626 return realPathWindows(current_thread, dir.handle, out_buffer);4612 return realPathWindows(dir.handle, out_buffer);
4627}4613}
46284614
4629const fileRealPath = switch (native_os) {4615const fileRealPath = switch (native_os) {
...@@ -4634,35 +4620,35 @@ const fileRealPath = switch (native_os) {...@@ -4634,35 +4620,35 @@ const fileRealPath = switch (native_os) {
4634fn fileRealPathWindows(userdata: ?*anyopaque, file: File, out_buffer: []u8) File.RealPathError!usize {4620fn fileRealPathWindows(userdata: ?*anyopaque, file: File, out_buffer: []u8) File.RealPathError!usize {
4635 if (native_os == .wasi) return error.OperationUnsupported;4621 if (native_os == .wasi) return error.OperationUnsupported;
4636 const t: *Threaded = @ptrCast(@alignCast(userdata));4622 const t: *Threaded = @ptrCast(@alignCast(userdata));
4637 const current_thread = Thread.getCurrent(t);4623 _ = t;
4638 return realPathWindows(current_thread, file.handle, out_buffer);4624 return realPathWindows(file.handle, out_buffer);
4639}4625}
46404626
4641fn fileRealPathPosix(userdata: ?*anyopaque, file: File, out_buffer: []u8) File.RealPathError!usize {4627fn fileRealPathPosix(userdata: ?*anyopaque, file: File, out_buffer: []u8) File.RealPathError!usize {
4642 if (native_os == .wasi) return error.OperationUnsupported;4628 if (native_os == .wasi) return error.OperationUnsupported;
4643 const t: *Threaded = @ptrCast(@alignCast(userdata));4629 const t: *Threaded = @ptrCast(@alignCast(userdata));
4644 const current_thread = Thread.getCurrent(t);4630 _ = t;
4645 return realPathPosix(current_thread, file.handle, out_buffer);4631 return realPathPosix(file.handle, out_buffer);
4646}4632}
46474633
4648fn realPathPosix(current_thread: *Thread, fd: posix.fd_t, out_buffer: []u8) File.RealPathError!usize {4634fn realPathPosix(fd: posix.fd_t, out_buffer: []u8) File.RealPathError!usize {
4649 switch (native_os) {4635 switch (native_os) {
4650 .netbsd, .dragonfly, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => {4636 .netbsd, .dragonfly, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => {
4651 var sufficient_buffer: [posix.PATH_MAX]u8 = undefined;4637 var sufficient_buffer: [posix.PATH_MAX]u8 = undefined;
4652 @memset(&sufficient_buffer, 0);4638 @memset(&sufficient_buffer, 0);
4653 try current_thread.beginSyscall();4639 const syscall: Syscall = try .start();
4654 while (true) {4640 while (true) {
4655 switch (posix.errno(posix.system.fcntl(fd, posix.F.GETPATH, &sufficient_buffer))) {4641 switch (posix.errno(posix.system.fcntl(fd, posix.F.GETPATH, &sufficient_buffer))) {
4656 .SUCCESS => {4642 .SUCCESS => {
4657 current_thread.endSyscall();4643 syscall.finish();
4658 break;4644 break;
4659 },4645 },
4660 .INTR => {4646 .INTR => {
4661 try current_thread.checkCancel();4647 try syscall.checkCancel();
4662 continue;4648 continue;
4663 },4649 },
4664 else => |e| {4650 else => |e| {
4665 current_thread.endSyscall();4651 syscall.finish();
4666 switch (e) {4652 switch (e) {
4667 .ACCES => return error.AccessDenied,4653 .ACCES => return error.AccessDenied,
4668 .BADF => return error.FileNotFound,4654 .BADF => return error.FileNotFound,
...@@ -4684,21 +4670,21 @@ fn realPathPosix(current_thread: *Thread, fd: posix.fd_t, out_buffer: []u8) File...@@ -4684,21 +4670,21 @@ fn realPathPosix(current_thread: *Thread, fd: posix.fd_t, out_buffer: []u8) File
4684 var procfs_buf: ["/proc/self/path/-2147483648\x00".len]u8 = undefined;4670 var procfs_buf: ["/proc/self/path/-2147483648\x00".len]u8 = undefined;
4685 const template = if (native_os == .illumos) "/proc/self/path/{d}" else "/proc/self/fd/{d}";4671 const template = if (native_os == .illumos) "/proc/self/path/{d}" else "/proc/self/fd/{d}";
4686 const proc_path = std.fmt.bufPrintSentinel(&procfs_buf, template, .{fd}, 0) catch unreachable;4672 const proc_path = std.fmt.bufPrintSentinel(&procfs_buf, template, .{fd}, 0) catch unreachable;
4687 try current_thread.beginSyscall();4673 const syscall: Syscall = try .start();
4688 while (true) {4674 while (true) {
4689 const rc = posix.system.readlink(proc_path, out_buffer.ptr, out_buffer.len);4675 const rc = posix.system.readlink(proc_path, out_buffer.ptr, out_buffer.len);
4690 switch (posix.errno(rc)) {4676 switch (posix.errno(rc)) {
4691 .SUCCESS => {4677 .SUCCESS => {
4692 current_thread.endSyscall();4678 syscall.finish();
4693 const len: usize = @bitCast(rc);4679 const len: usize = @bitCast(rc);
4694 return len;4680 return len;
4695 },4681 },
4696 .INTR => {4682 .INTR => {
4697 try current_thread.checkCancel();4683 try syscall.checkCancel();
4698 continue;4684 continue;
4699 },4685 },
4700 else => |e| {4686 else => |e| {
4701 current_thread.endSyscall();4687 syscall.finish();
4702 switch (e) {4688 switch (e) {
4703 .ACCES => return error.AccessDenied,4689 .ACCES => return error.AccessDenied,
4704 .FAULT => |err| return errnoBug(err),4690 .FAULT => |err| return errnoBug(err),
...@@ -4718,23 +4704,23 @@ fn realPathPosix(current_thread: *Thread, fd: posix.fd_t, out_buffer: []u8) File...@@ -4718,23 +4704,23 @@ fn realPathPosix(current_thread: *Thread, fd: posix.fd_t, out_buffer: []u8) File
4718 .freebsd => {4704 .freebsd => {
4719 var k_file: std.c.kinfo_file = undefined;4705 var k_file: std.c.kinfo_file = undefined;
4720 k_file.structsize = std.c.KINFO_FILE_SIZE;4706 k_file.structsize = std.c.KINFO_FILE_SIZE;
4721 try current_thread.beginSyscall();4707 const syscall: Syscall = try .start();
4722 while (true) {4708 while (true) {
4723 switch (posix.errno(std.c.fcntl(fd, std.c.F.KINFO, @intFromPtr(&k_file)))) {4709 switch (posix.errno(std.c.fcntl(fd, std.c.F.KINFO, @intFromPtr(&k_file)))) {
4724 .SUCCESS => {4710 .SUCCESS => {
4725 current_thread.endSyscall();4711 syscall.finish();
4726 break;4712 break;
4727 },4713 },
4728 .INTR => {4714 .INTR => {
4729 try current_thread.checkCancel();4715 try syscall.checkCancel();
4730 continue;4716 continue;
4731 },4717 },
4732 .BADF => {4718 .BADF => {
4733 current_thread.endSyscall();4719 syscall.finish();
4734 return error.FileNotFound;4720 return error.FileNotFound;
4735 },4721 },
4736 else => |err| {4722 else => |err| {
4737 current_thread.endSyscall();4723 syscall.finish();
4738 return posix.unexpectedErrno(err);4724 return posix.unexpectedErrno(err);
4739 },4725 },
4740 }4726 }
...@@ -4765,21 +4751,21 @@ fn dirDeleteFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) D...@@ -4765,21 +4751,21 @@ fn dirDeleteFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) D
4765fn dirDeleteFileWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.DeleteFileError!void {4751fn dirDeleteFileWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.DeleteFileError!void {
4766 if (builtin.link_libc) return dirDeleteFilePosix(userdata, dir, sub_path);4752 if (builtin.link_libc) return dirDeleteFilePosix(userdata, dir, sub_path);
4767 const t: *Threaded = @ptrCast(@alignCast(userdata));4753 const t: *Threaded = @ptrCast(@alignCast(userdata));
4768 const current_thread = Thread.getCurrent(t);4754 _ = t;
4769 try current_thread.beginSyscall();4755 const syscall: Syscall = try .start();
4770 while (true) {4756 while (true) {
4771 const res = std.os.wasi.path_unlink_file(dir.handle, sub_path.ptr, sub_path.len);4757 const res = std.os.wasi.path_unlink_file(dir.handle, sub_path.ptr, sub_path.len);
4772 switch (res) {4758 switch (res) {
4773 .SUCCESS => {4759 .SUCCESS => {
4774 current_thread.endSyscall();4760 syscall.finish();
4775 return;4761 return;
4776 },4762 },
4777 .INTR => {4763 .INTR => {
4778 try current_thread.checkCancel();4764 try syscall.checkCancel();
4779 continue;4765 continue;
4780 },4766 },
4781 else => |e| {4767 else => |e| {
4782 current_thread.endSyscall();4768 syscall.finish();
4783 switch (e) {4769 switch (e) {
4784 .ACCES => return error.AccessDenied,4770 .ACCES => return error.AccessDenied,
4785 .PERM => return error.PermissionDenied,4771 .PERM => return error.PermissionDenied,
...@@ -4806,20 +4792,20 @@ fn dirDeleteFileWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir....@@ -4806,20 +4792,20 @@ fn dirDeleteFileWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.
48064792
4807fn dirDeleteFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.DeleteFileError!void {4793fn dirDeleteFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.DeleteFileError!void {
4808 const t: *Threaded = @ptrCast(@alignCast(userdata));4794 const t: *Threaded = @ptrCast(@alignCast(userdata));
4809 const current_thread = Thread.getCurrent(t);4795 _ = t;
48104796
4811 var path_buffer: [posix.PATH_MAX]u8 = undefined;4797 var path_buffer: [posix.PATH_MAX]u8 = undefined;
4812 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);4798 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
48134799
4814 try current_thread.beginSyscall();4800 const syscall: Syscall = try .start();
4815 while (true) {4801 while (true) {
4816 switch (posix.errno(posix.system.unlinkat(dir.handle, sub_path_posix, 0))) {4802 switch (posix.errno(posix.system.unlinkat(dir.handle, sub_path_posix, 0))) {
4817 .SUCCESS => {4803 .SUCCESS => {
4818 current_thread.endSyscall();4804 syscall.finish();
4819 return;4805 return;
4820 },4806 },
4821 .INTR => {4807 .INTR => {
4822 try current_thread.checkCancel();4808 try syscall.checkCancel();
4823 continue;4809 continue;
4824 },4810 },
4825 // Some systems return permission errors when trying to delete a4811 // Some systems return permission errors when trying to delete a
...@@ -4831,15 +4817,15 @@ fn dirDeleteFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir...@@ -4831,15 +4817,15 @@ fn dirDeleteFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir
4831 // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them).4817 // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them).
4832 var st = std.mem.zeroes(posix.Stat);4818 var st = std.mem.zeroes(posix.Stat);
4833 while (true) {4819 while (true) {
4834 try current_thread.checkCancel();4820 try syscall.checkCancel();
4835 switch (posix.errno(fstatat_sym(dir.handle, sub_path_posix, &st, posix.AT.SYMLINK_NOFOLLOW))) {4821 switch (posix.errno(fstatat_sym(dir.handle, sub_path_posix, &st, posix.AT.SYMLINK_NOFOLLOW))) {
4836 .SUCCESS => {4822 .SUCCESS => {
4837 current_thread.endSyscall();4823 syscall.finish();
4838 break;4824 break;
4839 },4825 },
4840 .INTR => continue,4826 .INTR => continue,
4841 else => {4827 else => {
4842 current_thread.endSyscall();4828 syscall.finish();
4843 return error.PermissionDenied;4829 return error.PermissionDenied;
4844 },4830 },
4845 }4831 }
...@@ -4851,12 +4837,12 @@ fn dirDeleteFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir...@@ -4851,12 +4837,12 @@ fn dirDeleteFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir
4851 return error.PermissionDenied;4837 return error.PermissionDenied;
4852 },4838 },
4853 else => {4839 else => {
4854 current_thread.endSyscall();4840 syscall.finish();
4855 return error.PermissionDenied;4841 return error.PermissionDenied;
4856 },4842 },
4857 },4843 },
4858 else => |e| {4844 else => |e| {
4859 current_thread.endSyscall();4845 syscall.finish();
4860 switch (e) {4846 switch (e) {
4861 .ACCES => return error.AccessDenied,4847 .ACCES => return error.AccessDenied,
4862 .BUSY => return error.FileBusy,4848 .BUSY => return error.FileBusy,
...@@ -4896,10 +4882,10 @@ fn dirDeleteDirWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Di...@@ -4896,10 +4882,10 @@ fn dirDeleteDirWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Di
48964882
4897fn dirDeleteWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, remove_dir: bool) (Dir.DeleteDirError || Dir.DeleteFileError)!void {4883fn dirDeleteWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, remove_dir: bool) (Dir.DeleteDirError || Dir.DeleteFileError)!void {
4898 const t: *Threaded = @ptrCast(@alignCast(userdata));4884 const t: *Threaded = @ptrCast(@alignCast(userdata));
4899 const current_thread = Thread.getCurrent(t);4885 _ = t;
4900 const w = windows;4886 const w = windows;
49014887
4902 try current_thread.checkCancel();4888 try Thread.checkCancel();
49034889
4904 const sub_path_w_buf = try w.sliceToPrefixedFileW(dir.handle, sub_path);4890 const sub_path_w_buf = try w.sliceToPrefixedFileW(dir.handle, sub_path);
4905 const sub_path_w = sub_path_w_buf.span();4891 const sub_path_w = sub_path_w_buf.span();
...@@ -4979,7 +4965,7 @@ fn dirDeleteWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, remov...@@ -4979,7 +4965,7 @@ fn dirDeleteWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, remov
4979 // The strategy here is just to try using FileDispositionInformationEx and fall back to4965 // The strategy here is just to try using FileDispositionInformationEx and fall back to
4980 // FileDispositionInformation if the return value lets us know that some aspect of it is not supported.4966 // FileDispositionInformation if the return value lets us know that some aspect of it is not supported.
4981 const need_fallback = need_fallback: {4967 const need_fallback = need_fallback: {
4982 try current_thread.checkCancel();4968 try Thread.checkCancel();
49834969
4984 // Deletion with posix semantics if the filesystem supports it.4970 // Deletion with posix semantics if the filesystem supports it.
4985 const info: w.FILE.DISPOSITION.INFORMATION.EX = .{ .Flags = .{4971 const info: w.FILE.DISPOSITION.INFORMATION.EX = .{ .Flags = .{
...@@ -5010,7 +4996,7 @@ fn dirDeleteWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, remov...@@ -5010,7 +4996,7 @@ fn dirDeleteWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, remov
5010 };4996 };
50114997
5012 if (need_fallback) {4998 if (need_fallback) {
5013 try current_thread.checkCancel();4999 try Thread.checkCancel();
50145000
5015 // Deletion with file pending semantics, which requires waiting or moving5001 // Deletion with file pending semantics, which requires waiting or moving
5016 // files to get them removed (from here).5002 // files to get them removed (from here).
...@@ -5041,22 +5027,22 @@ fn dirDeleteDirWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.D...@@ -5041,22 +5027,22 @@ fn dirDeleteDirWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.D
5041 if (builtin.link_libc) return dirDeleteDirPosix(userdata, dir, sub_path);5027 if (builtin.link_libc) return dirDeleteDirPosix(userdata, dir, sub_path);
50425028
5043 const t: *Threaded = @ptrCast(@alignCast(userdata));5029 const t: *Threaded = @ptrCast(@alignCast(userdata));
5044 const current_thread = Thread.getCurrent(t);5030 _ = t;
50455031
5046 try current_thread.beginSyscall();5032 const syscall: Syscall = try .start();
5047 while (true) {5033 while (true) {
5048 const res = std.os.wasi.path_remove_directory(dir.handle, sub_path.ptr, sub_path.len);5034 const res = std.os.wasi.path_remove_directory(dir.handle, sub_path.ptr, sub_path.len);
5049 switch (res) {5035 switch (res) {
5050 .SUCCESS => {5036 .SUCCESS => {
5051 current_thread.endSyscall();5037 syscall.finish();
5052 return;5038 return;
5053 },5039 },
5054 .INTR => {5040 .INTR => {
5055 try current_thread.checkCancel();5041 try syscall.checkCancel();
5056 continue;5042 continue;
5057 },5043 },
5058 else => |e| {5044 else => |e| {
5059 current_thread.endSyscall();5045 syscall.finish();
5060 switch (e) {5046 switch (e) {
5061 .ACCES => return error.AccessDenied,5047 .ACCES => return error.AccessDenied,
5062 .PERM => return error.PermissionDenied,5048 .PERM => return error.PermissionDenied,
...@@ -5083,24 +5069,24 @@ fn dirDeleteDirWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.D...@@ -5083,24 +5069,24 @@ fn dirDeleteDirWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.D
50835069
5084fn dirDeleteDirPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.DeleteDirError!void {5070fn dirDeleteDirPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.DeleteDirError!void {
5085 const t: *Threaded = @ptrCast(@alignCast(userdata));5071 const t: *Threaded = @ptrCast(@alignCast(userdata));
5086 const current_thread = Thread.getCurrent(t);5072 _ = t;
50875073
5088 var path_buffer: [posix.PATH_MAX]u8 = undefined;5074 var path_buffer: [posix.PATH_MAX]u8 = undefined;
5089 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);5075 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
50905076
5091 try current_thread.beginSyscall();5077 const syscall: Syscall = try .start();
5092 while (true) {5078 while (true) {
5093 switch (posix.errno(posix.system.unlinkat(dir.handle, sub_path_posix, posix.AT.REMOVEDIR))) {5079 switch (posix.errno(posix.system.unlinkat(dir.handle, sub_path_posix, posix.AT.REMOVEDIR))) {
5094 .SUCCESS => {5080 .SUCCESS => {
5095 current_thread.endSyscall();5081 syscall.finish();
5096 return;5082 return;
5097 },5083 },
5098 .INTR => {5084 .INTR => {
5099 try current_thread.checkCancel();5085 try syscall.checkCancel();
5100 continue;5086 continue;
5101 },5087 },
5102 else => |e| {5088 else => |e| {
5103 current_thread.endSyscall();5089 syscall.finish();
5104 switch (e) {5090 switch (e) {
5105 .ACCES => return error.AccessDenied,5091 .ACCES => return error.AccessDenied,
5106 .PERM => return error.PermissionDenied,5092 .PERM => return error.PermissionDenied,
...@@ -5141,7 +5127,7 @@ fn dirRenameWindows(...@@ -5141,7 +5127,7 @@ fn dirRenameWindows(
5141) Dir.RenameError!void {5127) Dir.RenameError!void {
5142 const w = windows;5128 const w = windows;
5143 const t: *Threaded = @ptrCast(@alignCast(userdata));5129 const t: *Threaded = @ptrCast(@alignCast(userdata));
5144 const current_thread = Thread.getCurrent(t);5130 _ = t;
51455131
5146 const old_path_w_buf = try windows.sliceToPrefixedFileW(old_dir.handle, old_sub_path);5132 const old_path_w_buf = try windows.sliceToPrefixedFileW(old_dir.handle, old_sub_path);
5147 const old_path_w = old_path_w_buf.span();5133 const old_path_w = old_path_w_buf.span();
...@@ -5149,7 +5135,7 @@ fn dirRenameWindows(...@@ -5149,7 +5135,7 @@ fn dirRenameWindows(
5149 const new_path_w = new_path_w_buf.span();5135 const new_path_w = new_path_w_buf.span();
5150 const replace_if_exists = true;5136 const replace_if_exists = true;
51515137
5152 try current_thread.checkCancel();5138 try Thread.checkCancel();
51535139
5154 const src_fd = w.OpenFile(old_path_w, .{5140 const src_fd = w.OpenFile(old_path_w, .{
5155 .dir = old_dir.handle,5141 .dir = old_dir.handle,
...@@ -5258,18 +5244,18 @@ fn dirRenameWasi(...@@ -5258,18 +5244,18 @@ fn dirRenameWasi(
5258 if (builtin.link_libc) return dirRenamePosix(userdata, old_dir, old_sub_path, new_dir, new_sub_path);5244 if (builtin.link_libc) return dirRenamePosix(userdata, old_dir, old_sub_path, new_dir, new_sub_path);
52595245
5260 const t: *Threaded = @ptrCast(@alignCast(userdata));5246 const t: *Threaded = @ptrCast(@alignCast(userdata));
5261 const current_thread = Thread.getCurrent(t);5247 _ = t;
52625248
5263 try current_thread.beginSyscall();5249 const syscall: Syscall = try .start();
5264 while (true) {5250 while (true) {
5265 switch (std.os.wasi.path_rename(old_dir.handle, old_sub_path.ptr, old_sub_path.len, new_dir.handle, new_sub_path.ptr, new_sub_path.len)) {5251 switch (std.os.wasi.path_rename(old_dir.handle, old_sub_path.ptr, old_sub_path.len, new_dir.handle, new_sub_path.ptr, new_sub_path.len)) {
5266 .SUCCESS => return current_thread.endSyscall(),5252 .SUCCESS => return syscall.finish(),
5267 .INTR => {5253 .INTR => {
5268 try current_thread.checkCancel();5254 try syscall.checkCancel();
5269 continue;5255 continue;
5270 },5256 },
5271 else => |e| {5257 else => |e| {
5272 current_thread.endSyscall();5258 syscall.finish();
5273 switch (e) {5259 switch (e) {
5274 .ACCES => return error.AccessDenied,5260 .ACCES => return error.AccessDenied,
5275 .PERM => return error.PermissionDenied,5261 .PERM => return error.PermissionDenied,
...@@ -5306,7 +5292,7 @@ fn dirRenamePosix(...@@ -5306,7 +5292,7 @@ fn dirRenamePosix(
5306 new_sub_path: []const u8,5292 new_sub_path: []const u8,
5307) Dir.RenameError!void {5293) Dir.RenameError!void {
5308 const t: *Threaded = @ptrCast(@alignCast(userdata));5294 const t: *Threaded = @ptrCast(@alignCast(userdata));
5309 const current_thread = Thread.getCurrent(t);5295 _ = t;
53105296
5311 var old_path_buffer: [posix.PATH_MAX]u8 = undefined;5297 var old_path_buffer: [posix.PATH_MAX]u8 = undefined;
5312 var new_path_buffer: [posix.PATH_MAX]u8 = undefined;5298 var new_path_buffer: [posix.PATH_MAX]u8 = undefined;
...@@ -5314,16 +5300,16 @@ fn dirRenamePosix(...@@ -5314,16 +5300,16 @@ fn dirRenamePosix(
5314 const old_sub_path_posix = try pathToPosix(old_sub_path, &old_path_buffer);5300 const old_sub_path_posix = try pathToPosix(old_sub_path, &old_path_buffer);
5315 const new_sub_path_posix = try pathToPosix(new_sub_path, &new_path_buffer);5301 const new_sub_path_posix = try pathToPosix(new_sub_path, &new_path_buffer);
53165302
5317 try current_thread.beginSyscall();5303 const syscall: Syscall = try .start();
5318 while (true) {5304 while (true) {
5319 switch (posix.errno(posix.system.renameat(old_dir.handle, old_sub_path_posix, new_dir.handle, new_sub_path_posix))) {5305 switch (posix.errno(posix.system.renameat(old_dir.handle, old_sub_path_posix, new_dir.handle, new_sub_path_posix))) {
5320 .SUCCESS => return current_thread.endSyscall(),5306 .SUCCESS => return syscall.finish(),
5321 .INTR => {5307 .INTR => {
5322 try current_thread.checkCancel();5308 try syscall.checkCancel();
5323 continue;5309 continue;
5324 },5310 },
5325 else => |e| {5311 else => |e| {
5326 current_thread.endSyscall();5312 syscall.finish();
5327 switch (e) {5313 switch (e) {
5328 .ACCES => return error.AccessDenied,5314 .ACCES => return error.AccessDenied,
5329 .PERM => return error.PermissionDenied,5315 .PERM => return error.PermissionDenied,
...@@ -5365,10 +5351,10 @@ fn dirSymLinkWindows(...@@ -5365,10 +5351,10 @@ fn dirSymLinkWindows(
5365 flags: Dir.SymLinkFlags,5351 flags: Dir.SymLinkFlags,
5366) Dir.SymLinkError!void {5352) Dir.SymLinkError!void {
5367 const t: *Threaded = @ptrCast(@alignCast(userdata));5353 const t: *Threaded = @ptrCast(@alignCast(userdata));
5368 const current_thread = Thread.getCurrent(t);5354 _ = t;
5369 const w = windows;5355 const w = windows;
53705356
5371 try current_thread.checkCancel();5357 try Thread.checkCancel();
53725358
5373 // Target path does not use sliceToPrefixedFileW because certain paths5359 // Target path does not use sliceToPrefixedFileW because certain paths
5374 // are handled differently when creating a symlink than they would be5360 // are handled differently when creating a symlink than they would be
...@@ -5492,18 +5478,18 @@ fn dirSymLinkWasi(...@@ -5492,18 +5478,18 @@ fn dirSymLinkWasi(
5492 if (builtin.link_libc) return dirSymLinkPosix(userdata, dir, target_path, sym_link_path, flags);5478 if (builtin.link_libc) return dirSymLinkPosix(userdata, dir, target_path, sym_link_path, flags);
54935479
5494 const t: *Threaded = @ptrCast(@alignCast(userdata));5480 const t: *Threaded = @ptrCast(@alignCast(userdata));
5495 const current_thread = Thread.getCurrent(t);5481 _ = t;
54965482
5497 try current_thread.beginSyscall();5483 const syscall: Syscall = try .start();
5498 while (true) {5484 while (true) {
5499 switch (std.os.wasi.path_symlink(target_path.ptr, target_path.len, dir.handle, sym_link_path.ptr, sym_link_path.len)) {5485 switch (std.os.wasi.path_symlink(target_path.ptr, target_path.len, dir.handle, sym_link_path.ptr, sym_link_path.len)) {
5500 .SUCCESS => return current_thread.endSyscall(),5486 .SUCCESS => return syscall.finish(),
5501 .INTR => {5487 .INTR => {
5502 try current_thread.checkCancel();5488 try syscall.checkCancel();
5503 continue;5489 continue;
5504 },5490 },
5505 else => |e| {5491 else => |e| {
5506 current_thread.endSyscall();5492 syscall.finish();
5507 switch (e) {5493 switch (e) {
5508 .FAULT => |err| return errnoBug(err),5494 .FAULT => |err| return errnoBug(err),
5509 .INVAL => |err| return errnoBug(err),5495 .INVAL => |err| return errnoBug(err),
...@@ -5538,7 +5524,7 @@ fn dirSymLinkPosix(...@@ -5538,7 +5524,7 @@ fn dirSymLinkPosix(
5538) Dir.SymLinkError!void {5524) Dir.SymLinkError!void {
5539 _ = flags;5525 _ = flags;
5540 const t: *Threaded = @ptrCast(@alignCast(userdata));5526 const t: *Threaded = @ptrCast(@alignCast(userdata));
5541 const current_thread = Thread.getCurrent(t);5527 _ = t;
55425528
5543 var target_path_buffer: [posix.PATH_MAX]u8 = undefined;5529 var target_path_buffer: [posix.PATH_MAX]u8 = undefined;
5544 var sym_link_path_buffer: [posix.PATH_MAX]u8 = undefined;5530 var sym_link_path_buffer: [posix.PATH_MAX]u8 = undefined;
...@@ -5546,16 +5532,16 @@ fn dirSymLinkPosix(...@@ -5546,16 +5532,16 @@ fn dirSymLinkPosix(
5546 const target_path_posix = try pathToPosix(target_path, &target_path_buffer);5532 const target_path_posix = try pathToPosix(target_path, &target_path_buffer);
5547 const sym_link_path_posix = try pathToPosix(sym_link_path, &sym_link_path_buffer);5533 const sym_link_path_posix = try pathToPosix(sym_link_path, &sym_link_path_buffer);
55485534
5549 try current_thread.beginSyscall();5535 const syscall: Syscall = try .start();
5550 while (true) {5536 while (true) {
5551 switch (posix.errno(posix.system.symlinkat(target_path_posix, dir.handle, sym_link_path_posix))) {5537 switch (posix.errno(posix.system.symlinkat(target_path_posix, dir.handle, sym_link_path_posix))) {
5552 .SUCCESS => return current_thread.endSyscall(),5538 .SUCCESS => return syscall.finish(),
5553 .INTR => {5539 .INTR => {
5554 try current_thread.checkCancel();5540 try syscall.checkCancel();
5555 continue;5541 continue;
5556 },5542 },
5557 else => |e| {5543 else => |e| {
5558 current_thread.endSyscall();5544 syscall.finish();
5559 switch (e) {5545 switch (e) {
5560 .FAULT => |err| return errnoBug(err),5546 .FAULT => |err| return errnoBug(err),
5561 .INVAL => |err| return errnoBug(err),5547 .INVAL => |err| return errnoBug(err),
...@@ -5587,10 +5573,10 @@ const dirReadLink = switch (native_os) {...@@ -5587,10 +5573,10 @@ const dirReadLink = switch (native_os) {
55875573
5588fn dirReadLinkWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize {5574fn dirReadLinkWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize {
5589 const t: *Threaded = @ptrCast(@alignCast(userdata));5575 const t: *Threaded = @ptrCast(@alignCast(userdata));
5590 const current_thread = Thread.getCurrent(t);5576 _ = t;
5591 const w = windows;5577 const w = windows;
55925578
5593 try current_thread.checkCancel();5579 try Thread.checkCancel();
55945580
5595 var sub_path_w_buf = try windows.sliceToPrefixedFileW(dir.handle, sub_path);5581 var sub_path_w_buf = try windows.sliceToPrefixedFileW(dir.handle, sub_path);
55965582
...@@ -5606,22 +5592,22 @@ fn dirReadLinkWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer...@@ -5606,22 +5592,22 @@ fn dirReadLinkWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer
5606 if (builtin.link_libc) return dirReadLinkPosix(userdata, dir, sub_path, buffer);5592 if (builtin.link_libc) return dirReadLinkPosix(userdata, dir, sub_path, buffer);
56075593
5608 const t: *Threaded = @ptrCast(@alignCast(userdata));5594 const t: *Threaded = @ptrCast(@alignCast(userdata));
5609 const current_thread = Thread.getCurrent(t);5595 _ = t;
56105596
5611 var n: usize = undefined;5597 var n: usize = undefined;
5612 try current_thread.beginSyscall();5598 const syscall: Syscall = try .start();
5613 while (true) {5599 while (true) {
5614 switch (std.os.wasi.path_readlink(dir.handle, sub_path.ptr, sub_path.len, buffer.ptr, buffer.len, &n)) {5600 switch (std.os.wasi.path_readlink(dir.handle, sub_path.ptr, sub_path.len, buffer.ptr, buffer.len, &n)) {
5615 .SUCCESS => {5601 .SUCCESS => {
5616 current_thread.endSyscall();5602 syscall.finish();
5617 return n;5603 return n;
5618 },5604 },
5619 .INTR => {5605 .INTR => {
5620 try current_thread.checkCancel();5606 try syscall.checkCancel();
5621 continue;5607 continue;
5622 },5608 },
5623 else => |e| {5609 else => |e| {
5624 current_thread.endSyscall();5610 syscall.finish();
5625 switch (e) {5611 switch (e) {
5626 .ACCES => return error.AccessDenied,5612 .ACCES => return error.AccessDenied,
5627 .FAULT => |err| return errnoBug(err),5613 .FAULT => |err| return errnoBug(err),
...@@ -5643,26 +5629,26 @@ fn dirReadLinkWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer...@@ -5643,26 +5629,26 @@ fn dirReadLinkWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer
56435629
5644fn dirReadLinkPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize {5630fn dirReadLinkPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize {
5645 const t: *Threaded = @ptrCast(@alignCast(userdata));5631 const t: *Threaded = @ptrCast(@alignCast(userdata));
5646 const current_thread = Thread.getCurrent(t);5632 _ = t;
56475633
5648 var sub_path_buffer: [posix.PATH_MAX]u8 = undefined;5634 var sub_path_buffer: [posix.PATH_MAX]u8 = undefined;
5649 const sub_path_posix = try pathToPosix(sub_path, &sub_path_buffer);5635 const sub_path_posix = try pathToPosix(sub_path, &sub_path_buffer);
56505636
5651 try current_thread.beginSyscall();5637 const syscall: Syscall = try .start();
5652 while (true) {5638 while (true) {
5653 const rc = posix.system.readlinkat(dir.handle, sub_path_posix, buffer.ptr, buffer.len);5639 const rc = posix.system.readlinkat(dir.handle, sub_path_posix, buffer.ptr, buffer.len);
5654 switch (posix.errno(rc)) {5640 switch (posix.errno(rc)) {
5655 .SUCCESS => {5641 .SUCCESS => {
5656 current_thread.endSyscall();5642 syscall.finish();
5657 const len: usize = @bitCast(rc);5643 const len: usize = @bitCast(rc);
5658 return len;5644 return len;
5659 },5645 },
5660 .INTR => {5646 .INTR => {
5661 try current_thread.checkCancel();5647 try syscall.checkCancel();
5662 continue;5648 continue;
5663 },5649 },
5664 else => |e| {5650 else => |e| {
5665 current_thread.endSyscall();5651 syscall.finish();
5666 switch (e) {5652 switch (e) {
5667 .ACCES => return error.AccessDenied,5653 .ACCES => return error.AccessDenied,
5668 .FAULT => |err| return errnoBug(err),5654 .FAULT => |err| return errnoBug(err),
...@@ -5697,8 +5683,8 @@ fn dirSetPermissionsWindows(userdata: ?*anyopaque, dir: Dir, permissions: Dir.Pe...@@ -5697,8 +5683,8 @@ fn dirSetPermissionsWindows(userdata: ?*anyopaque, dir: Dir, permissions: Dir.Pe
5697fn dirSetPermissionsPosix(userdata: ?*anyopaque, dir: Dir, permissions: Dir.Permissions) Dir.SetPermissionsError!void {5683fn dirSetPermissionsPosix(userdata: ?*anyopaque, dir: Dir, permissions: Dir.Permissions) Dir.SetPermissionsError!void {
5698 if (@sizeOf(Dir.Permissions) == 0) return;5684 if (@sizeOf(Dir.Permissions) == 0) return;
5699 const t: *Threaded = @ptrCast(@alignCast(userdata));5685 const t: *Threaded = @ptrCast(@alignCast(userdata));
5700 const current_thread = Thread.getCurrent(t);5686 _ = t;
5701 return setPermissionsPosix(current_thread, dir.handle, permissions.toMode());5687 return setPermissionsPosix(dir.handle, permissions.toMode());
5702}5688}
57035689
5704fn dirSetFilePermissions(5690fn dirSetFilePermissions(
...@@ -5711,7 +5697,6 @@ fn dirSetFilePermissions(...@@ -5711,7 +5697,6 @@ fn dirSetFilePermissions(
5711 if (@sizeOf(Dir.Permissions) == 0) return;5697 if (@sizeOf(Dir.Permissions) == 0) return;
5712 if (is_windows) @panic("TODO implement dirSetFilePermissions windows");5698 if (is_windows) @panic("TODO implement dirSetFilePermissions windows");
5713 const t: *Threaded = @ptrCast(@alignCast(userdata));5699 const t: *Threaded = @ptrCast(@alignCast(userdata));
5714 const current_thread = Thread.getCurrent(t);
57155700
5716 var path_buffer: [posix.PATH_MAX]u8 = undefined;5701 var path_buffer: [posix.PATH_MAX]u8 = undefined;
5717 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);5702 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
...@@ -5719,12 +5704,11 @@ fn dirSetFilePermissions(...@@ -5719,12 +5704,11 @@ fn dirSetFilePermissions(
5719 const mode = permissions.toMode();5704 const mode = permissions.toMode();
5720 const flags: u32 = if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0;5705 const flags: u32 = if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0;
57215706
5722 return posixFchmodat(t, current_thread, dir.handle, sub_path_posix, mode, flags);5707 return posixFchmodat(t, dir.handle, sub_path_posix, mode, flags);
5723}5708}
57245709
5725fn posixFchmodat(5710fn posixFchmodat(
5726 t: *Threaded,5711 t: *Threaded,
5727 current_thread: *Thread,
5728 dir_fd: posix.fd_t,5712 dir_fd: posix.fd_t,
5729 path: [*:0]const u8,5713 path: [*:0]const u8,
5730 mode: posix.mode_t,5714 mode: posix.mode_t,
...@@ -5733,20 +5717,20 @@ fn posixFchmodat(...@@ -5733,20 +5717,20 @@ fn posixFchmodat(
5733 // No special handling for linux is needed if we can use the libc fallback5717 // No special handling for linux is needed if we can use the libc fallback
5734 // or `flags` is empty. Glibc only added the fallback in 2.32.5718 // or `flags` is empty. Glibc only added the fallback in 2.32.
5735 if (have_fchmodat_flags or flags == 0) {5719 if (have_fchmodat_flags or flags == 0) {
5736 try current_thread.beginSyscall();5720 const syscall: Syscall = try .start();
5737 while (true) {5721 while (true) {
5738 const rc = if (have_fchmodat_flags or builtin.link_libc)5722 const rc = if (have_fchmodat_flags or builtin.link_libc)
5739 posix.system.fchmodat(dir_fd, path, mode, flags)5723 posix.system.fchmodat(dir_fd, path, mode, flags)
5740 else5724 else
5741 posix.system.fchmodat(dir_fd, path, mode);5725 posix.system.fchmodat(dir_fd, path, mode);
5742 switch (posix.errno(rc)) {5726 switch (posix.errno(rc)) {
5743 .SUCCESS => return current_thread.endSyscall(),5727 .SUCCESS => return syscall.finish(),
5744 .INTR => {5728 .INTR => {
5745 try current_thread.checkCancel();5729 try syscall.checkCancel();
5746 continue;5730 continue;
5747 },5731 },
5748 else => |e| {5732 else => |e| {
5749 current_thread.endSyscall();5733 syscall.finish();
5750 switch (e) {5734 switch (e) {
5751 .BADF => |err| return errnoBug(err),5735 .BADF => |err| return errnoBug(err),
5752 .FAULT => |err| return errnoBug(err),5736 .FAULT => |err| return errnoBug(err),
...@@ -5771,20 +5755,20 @@ fn posixFchmodat(...@@ -5771,20 +5755,20 @@ fn posixFchmodat(
5771 }5755 }
57725756
5773 if (@atomicLoad(UseFchmodat2, &t.use_fchmodat2, .monotonic) == .disabled)5757 if (@atomicLoad(UseFchmodat2, &t.use_fchmodat2, .monotonic) == .disabled)
5774 return fchmodatFallback(current_thread, dir_fd, path, mode);5758 return fchmodatFallback(dir_fd, path, mode);
57755759
5776 comptime assert(native_os == .linux);5760 comptime assert(native_os == .linux);
57775761
5778 try current_thread.beginSyscall();5762 const syscall: Syscall = try .start();
5779 while (true) {5763 while (true) {
5780 switch (std.os.linux.errno(std.os.linux.fchmodat2(dir_fd, path, mode, flags))) {5764 switch (std.os.linux.errno(std.os.linux.fchmodat2(dir_fd, path, mode, flags))) {
5781 .SUCCESS => return current_thread.endSyscall(),5765 .SUCCESS => return syscall.finish(),
5782 .INTR => {5766 .INTR => {
5783 try current_thread.checkCancel();5767 try syscall.checkCancel();
5784 continue;5768 continue;
5785 },5769 },
5786 else => |e| {5770 else => |e| {
5787 current_thread.endSyscall();5771 syscall.finish();
5788 switch (e) {5772 switch (e) {
5789 .BADF => |err| return errnoBug(err),5773 .BADF => |err| return errnoBug(err),
5790 .FAULT => |err| return errnoBug(err),5774 .FAULT => |err| return errnoBug(err),
...@@ -5800,7 +5784,7 @@ fn posixFchmodat(...@@ -5800,7 +5784,7 @@ fn posixFchmodat(
5800 .ROFS => return error.ReadOnlyFileSystem,5784 .ROFS => return error.ReadOnlyFileSystem,
5801 .NOSYS => {5785 .NOSYS => {
5802 @atomicStore(UseFchmodat2, &t.use_fchmodat2, .disabled, .monotonic);5786 @atomicStore(UseFchmodat2, &t.use_fchmodat2, .disabled, .monotonic);
5803 return fchmodatFallback(current_thread, dir_fd, path, mode);5787 return fchmodatFallback(dir_fd, path, mode);
5804 },5788 },
5805 else => |err| return posix.unexpectedErrno(err),5789 else => |err| return posix.unexpectedErrno(err),
5806 }5790 }
...@@ -5810,7 +5794,6 @@ fn posixFchmodat(...@@ -5810,7 +5794,6 @@ fn posixFchmodat(
5810}5794}
58115795
5812fn fchmodatFallback(5796fn fchmodatFallback(
5813 current_thread: *Thread,
5814 dir_fd: posix.fd_t,5797 dir_fd: posix.fd_t,
5815 path: [*:0]const u8,5798 path: [*:0]const u8,
5816 mode: posix.mode_t,5799 mode: posix.mode_t,
...@@ -5828,64 +5811,68 @@ fn fchmodatFallback(...@@ -5828,64 +5811,68 @@ fn fchmodatFallback(
5828 // 2. Stat the fd and check if it isn't a symbolic link.5811 // 2. Stat the fd and check if it isn't a symbolic link.
5829 // 3. Generate the procfs reference to the fd via `/proc/self/fd/{fd}`.5812 // 3. Generate the procfs reference to the fd via `/proc/self/fd/{fd}`.
5830 // 4. Pass the procfs path to `chmod` with the `mode`.5813 // 4. Pass the procfs path to `chmod` with the `mode`.
5831 try current_thread.beginSyscall();5814 const path_fd: posix.fd_t = fd: {
5832 const path_fd: posix.fd_t = while (true) {5815 const syscall: Syscall = try .start();
5833 const rc = posix.system.openat(dir_fd, path, .{5816 while (true) {
5834 .PATH = true,5817 const rc = posix.system.openat(dir_fd, path, .{
5835 .NOFOLLOW = true,5818 .PATH = true,
5836 .CLOEXEC = true,5819 .NOFOLLOW = true,
5837 }, @as(posix.mode_t, 0));5820 .CLOEXEC = true,
5838 switch (posix.errno(rc)) {5821 }, @as(posix.mode_t, 0));
5839 .SUCCESS => {5822 switch (posix.errno(rc)) {
5840 current_thread.endSyscall();5823 .SUCCESS => {
5841 break @intCast(rc);5824 syscall.finish();
5842 },5825 break :fd @intCast(rc);
5843 .INTR => {5826 },
5844 try current_thread.checkCancel();5827 .INTR => {
5845 continue;5828 try syscall.checkCancel();
5846 },5829 continue;
5847 else => |e| {5830 },
5848 current_thread.endSyscall();5831 else => |e| {
5849 switch (e) {5832 syscall.finish();
5850 .FAULT => |err| return errnoBug(err),5833 switch (e) {
5851 .INVAL => |err| return errnoBug(err),5834 .FAULT => |err| return errnoBug(err),
5852 .ACCES => return error.AccessDenied,5835 .INVAL => |err| return errnoBug(err),
5853 .PERM => return error.PermissionDenied,5836 .ACCES => return error.AccessDenied,
5854 .LOOP => return error.SymLinkLoop,5837 .PERM => return error.PermissionDenied,
5855 .MFILE => return error.ProcessFdQuotaExceeded,5838 .LOOP => return error.SymLinkLoop,
5856 .NAMETOOLONG => return error.NameTooLong,5839 .MFILE => return error.ProcessFdQuotaExceeded,
5857 .NFILE => return error.SystemFdQuotaExceeded,5840 .NAMETOOLONG => return error.NameTooLong,
5858 .NOENT => return error.FileNotFound,5841 .NFILE => return error.SystemFdQuotaExceeded,
5859 .NOMEM => return error.SystemResources,5842 .NOENT => return error.FileNotFound,
5860 else => |err| return posix.unexpectedErrno(err),5843 .NOMEM => return error.SystemResources,
5861 }5844 else => |err| return posix.unexpectedErrno(err),
5862 },5845 }
5846 },
5847 }
5863 }5848 }
5864 };5849 };
5865 defer posix.close(path_fd);5850 defer posix.close(path_fd);
58665851
5867 try current_thread.beginSyscall();5852 const path_mode = mode: {
5868 const path_mode = while (true) {5853 const syscall: Syscall = try .start();
5869 var statx = std.mem.zeroes(std.os.linux.Statx);5854 while (true) {
5870 switch (sys.errno(sys.statx(path_fd, "", posix.AT.EMPTY_PATH, .{ .TYPE = true }, &statx))) {5855 var statx = std.mem.zeroes(std.os.linux.Statx);
5871 .SUCCESS => {5856 switch (sys.errno(sys.statx(path_fd, "", posix.AT.EMPTY_PATH, .{ .TYPE = true }, &statx))) {
5872 current_thread.endSyscall();5857 .SUCCESS => {
5873 if (!statx.mask.TYPE) return error.Unexpected;5858 syscall.finish();
5874 break statx.mode;5859 if (!statx.mask.TYPE) return error.Unexpected;
5875 },5860 break :mode statx.mode;
5876 .INTR => {5861 },
5877 try current_thread.checkCancel();5862 .INTR => {
5878 continue;5863 try syscall.checkCancel();
5879 },5864 continue;
5880 else => |e| {5865 },
5881 current_thread.endSyscall();5866 else => |e| {
5882 switch (e) {5867 syscall.finish();
5883 .ACCES => return error.AccessDenied,5868 switch (e) {
5884 .LOOP => return error.SymLinkLoop,5869 .ACCES => return error.AccessDenied,
5885 .NOMEM => return error.SystemResources,5870 .LOOP => return error.SymLinkLoop,
5886 else => |err| return posix.unexpectedErrno(err),5871 .NOMEM => return error.SystemResources,
5887 }5872 else => |err| return posix.unexpectedErrno(err),
5888 },5873 }
5874 },
5875 }
5889 }5876 }
5890 };5877 };
58915878
...@@ -5895,16 +5882,16 @@ fn fchmodatFallback(...@@ -5895,16 +5882,16 @@ fn fchmodatFallback(
58955882
5896 var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;5883 var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;
5897 const proc_path = std.fmt.bufPrintSentinel(&procfs_buf, "/proc/self/fd/{d}", .{path_fd}, 0) catch unreachable;5884 const proc_path = std.fmt.bufPrintSentinel(&procfs_buf, "/proc/self/fd/{d}", .{path_fd}, 0) catch unreachable;
5898 try current_thread.beginSyscall();5885 const syscall: Syscall = try .start();
5899 while (true) {5886 while (true) {
5900 switch (posix.errno(posix.system.chmod(proc_path, mode))) {5887 switch (posix.errno(posix.system.chmod(proc_path, mode))) {
5901 .SUCCESS => return current_thread.endSyscall(),5888 .SUCCESS => return syscall.finish(),
5902 .INTR => {5889 .INTR => {
5903 try current_thread.checkCancel();5890 try syscall.checkCancel();
5904 continue;5891 continue;
5905 },5892 },
5906 else => |e| {5893 else => |e| {
5907 current_thread.endSyscall();5894 syscall.finish();
5908 switch (e) {5895 switch (e) {
5909 .NOENT => return error.OperationUnsupported, // procfs not mounted.5896 .NOENT => return error.OperationUnsupported, // procfs not mounted.
5910 .BADF => |err| return errnoBug(err),5897 .BADF => |err| return errnoBug(err),
...@@ -5940,24 +5927,24 @@ fn dirSetOwnerUnsupported(userdata: ?*anyopaque, dir: Dir, owner: ?File.Uid, gro...@@ -5940,24 +5927,24 @@ fn dirSetOwnerUnsupported(userdata: ?*anyopaque, dir: Dir, owner: ?File.Uid, gro
5940fn dirSetOwnerPosix(userdata: ?*anyopaque, dir: Dir, owner: ?File.Uid, group: ?File.Gid) Dir.SetOwnerError!void {5927fn dirSetOwnerPosix(userdata: ?*anyopaque, dir: Dir, owner: ?File.Uid, group: ?File.Gid) Dir.SetOwnerError!void {
5941 if (!have_fchown) return error.Unexpected; // Unsupported OS, don't call this function.5928 if (!have_fchown) return error.Unexpected; // Unsupported OS, don't call this function.
5942 const t: *Threaded = @ptrCast(@alignCast(userdata));5929 const t: *Threaded = @ptrCast(@alignCast(userdata));
5943 const current_thread = Thread.getCurrent(t);5930 _ = t;
5944 const uid = owner orelse ~@as(posix.uid_t, 0);5931 const uid = owner orelse ~@as(posix.uid_t, 0);
5945 const gid = group orelse ~@as(posix.gid_t, 0);5932 const gid = group orelse ~@as(posix.gid_t, 0);
5946 return posixFchown(current_thread, dir.handle, uid, gid);5933 return posixFchown(dir.handle, uid, gid);
5947}5934}
59485935
5949fn posixFchown(current_thread: *Thread, fd: posix.fd_t, uid: posix.uid_t, gid: posix.gid_t) File.SetOwnerError!void {5936fn posixFchown(fd: posix.fd_t, uid: posix.uid_t, gid: posix.gid_t) File.SetOwnerError!void {
5950 comptime assert(have_fchown);5937 comptime assert(have_fchown);
5951 try current_thread.beginSyscall();5938 const syscall: Syscall = try .start();
5952 while (true) {5939 while (true) {
5953 switch (posix.errno(posix.system.fchown(fd, uid, gid))) {5940 switch (posix.errno(posix.system.fchown(fd, uid, gid))) {
5954 .SUCCESS => return current_thread.endSyscall(),5941 .SUCCESS => return syscall.finish(),
5955 .INTR => {5942 .INTR => {
5956 try current_thread.checkCancel();5943 try syscall.checkCancel();
5957 continue;5944 continue;
5958 },5945 },
5959 else => |e| {5946 else => |e| {
5960 current_thread.endSyscall();5947 syscall.finish();
5961 switch (e) {5948 switch (e) {
5962 .BADF => |err| return errnoBug(err), // likely fd refers to directory opened without `Dir.OpenOptions.iterate`5949 .BADF => |err| return errnoBug(err), // likely fd refers to directory opened without `Dir.OpenOptions.iterate`
5963 .FAULT => |err| return errnoBug(err),5950 .FAULT => |err| return errnoBug(err),
...@@ -5987,12 +5974,11 @@ fn dirSetFileOwner(...@@ -5987,12 +5974,11 @@ fn dirSetFileOwner(
5987) Dir.SetFileOwnerError!void {5974) Dir.SetFileOwnerError!void {
5988 if (!have_fchown) return error.Unexpected; // Unsupported OS, don't call this function.5975 if (!have_fchown) return error.Unexpected; // Unsupported OS, don't call this function.
5989 const t: *Threaded = @ptrCast(@alignCast(userdata));5976 const t: *Threaded = @ptrCast(@alignCast(userdata));
5990 const current_thread = Thread.getCurrent(t);5977 _ = t;
59915978
5992 var path_buffer: [posix.PATH_MAX]u8 = undefined;5979 var path_buffer: [posix.PATH_MAX]u8 = undefined;
5993 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);5980 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
59945981
5995 _ = current_thread;
5996 _ = dir;5982 _ = dir;
5997 _ = sub_path_posix;5983 _ = sub_path_posix;
5998 _ = owner;5984 _ = owner;
...@@ -6009,9 +5995,9 @@ const fileSync = switch (native_os) {...@@ -6009,9 +5995,9 @@ const fileSync = switch (native_os) {
60095995
6010fn fileSyncWindows(userdata: ?*anyopaque, file: File) File.SyncError!void {5996fn fileSyncWindows(userdata: ?*anyopaque, file: File) File.SyncError!void {
6011 const t: *Threaded = @ptrCast(@alignCast(userdata));5997 const t: *Threaded = @ptrCast(@alignCast(userdata));
6012 const current_thread = Thread.getCurrent(t);5998 _ = t;
60135999
6014 try current_thread.checkCancel();6000 try Thread.checkCancel();
60156001
6016 if (windows.kernel32.FlushFileBuffers(file.handle) != 0)6002 if (windows.kernel32.FlushFileBuffers(file.handle) != 0)
6017 return;6003 return;
...@@ -6027,17 +6013,17 @@ fn fileSyncWindows(userdata: ?*anyopaque, file: File) File.SyncError!void {...@@ -6027,17 +6013,17 @@ fn fileSyncWindows(userdata: ?*anyopaque, file: File) File.SyncError!void {
60276013
6028fn fileSyncPosix(userdata: ?*anyopaque, file: File) File.SyncError!void {6014fn fileSyncPosix(userdata: ?*anyopaque, file: File) File.SyncError!void {
6029 const t: *Threaded = @ptrCast(@alignCast(userdata));6015 const t: *Threaded = @ptrCast(@alignCast(userdata));
6030 const current_thread = Thread.getCurrent(t);6016 _ = t;
6031 try current_thread.beginSyscall();6017 const syscall: Syscall = try .start();
6032 while (true) {6018 while (true) {
6033 switch (posix.errno(posix.system.fsync(file.handle))) {6019 switch (posix.errno(posix.system.fsync(file.handle))) {
6034 .SUCCESS => return current_thread.endSyscall(),6020 .SUCCESS => return syscall.finish(),
6035 .INTR => {6021 .INTR => {
6036 try current_thread.checkCancel();6022 try syscall.checkCancel();
6037 continue;6023 continue;
6038 },6024 },
6039 else => |e| {6025 else => |e| {
6040 current_thread.endSyscall();6026 syscall.finish();
6041 switch (e) {6027 switch (e) {
6042 .BADF => |err| return errnoBug(err),6028 .BADF => |err| return errnoBug(err),
6043 .INVAL => |err| return errnoBug(err),6029 .INVAL => |err| return errnoBug(err),
...@@ -6054,17 +6040,17 @@ fn fileSyncPosix(userdata: ?*anyopaque, file: File) File.SyncError!void {...@@ -6054,17 +6040,17 @@ fn fileSyncPosix(userdata: ?*anyopaque, file: File) File.SyncError!void {
60546040
6055fn fileSyncWasi(userdata: ?*anyopaque, file: File) File.SyncError!void {6041fn fileSyncWasi(userdata: ?*anyopaque, file: File) File.SyncError!void {
6056 const t: *Threaded = @ptrCast(@alignCast(userdata));6042 const t: *Threaded = @ptrCast(@alignCast(userdata));
6057 const current_thread = Thread.getCurrent(t);6043 _ = t;
6058 try current_thread.beginSyscall();6044 const syscall: Syscall = try .start();
6059 while (true) {6045 while (true) {
6060 switch (std.os.wasi.fd_sync(file.handle)) {6046 switch (std.os.wasi.fd_sync(file.handle)) {
6061 .SUCCESS => return current_thread.endSyscall(),6047 .SUCCESS => return syscall.finish(),
6062 .INTR => {6048 .INTR => {
6063 try current_thread.checkCancel();6049 try syscall.checkCancel();
6064 continue;6050 continue;
6065 },6051 },
6066 else => |e| {6052 else => |e| {
6067 current_thread.endSyscall();6053 syscall.finish();
6068 switch (e) {6054 switch (e) {
6069 .BADF => |err| return errnoBug(err),6055 .BADF => |err| return errnoBug(err),
6070 .INVAL => |err| return errnoBug(err),6056 .INVAL => |err| return errnoBug(err),
...@@ -6081,33 +6067,33 @@ fn fileSyncWasi(userdata: ?*anyopaque, file: File) File.SyncError!void {...@@ -6081,33 +6067,33 @@ fn fileSyncWasi(userdata: ?*anyopaque, file: File) File.SyncError!void {
60816067
6082fn fileIsTty(userdata: ?*anyopaque, file: File) Io.Cancelable!bool {6068fn fileIsTty(userdata: ?*anyopaque, file: File) Io.Cancelable!bool {
6083 const t: *Threaded = @ptrCast(@alignCast(userdata));6069 const t: *Threaded = @ptrCast(@alignCast(userdata));
6084 const current_thread = Thread.getCurrent(t);6070 _ = t;
6085 return isTty(current_thread, file);6071 return isTty(file);
6086}6072}
60876073
6088fn isTty(current_thread: *Thread, file: File) Io.Cancelable!bool {6074fn isTty(file: File) Io.Cancelable!bool {
6089 if (is_windows) {6075 if (is_windows) {
6090 if (try isCygwinPty(current_thread, file)) return true;6076 if (try isCygwinPty(file)) return true;
6091 try current_thread.checkCancel();6077 try Thread.checkCancel();
6092 var out: windows.DWORD = undefined;6078 var out: windows.DWORD = undefined;
6093 return windows.kernel32.GetConsoleMode(file.handle, &out) != 0;6079 return windows.kernel32.GetConsoleMode(file.handle, &out) != 0;
6094 }6080 }
60956081
6096 if (builtin.link_libc) {6082 if (builtin.link_libc) {
6097 try current_thread.beginSyscall();6083 const syscall: Syscall = try .start();
6098 while (true) {6084 while (true) {
6099 const rc = posix.system.isatty(file.handle);6085 const rc = posix.system.isatty(file.handle);
6100 switch (posix.errno(rc - 1)) {6086 switch (posix.errno(rc - 1)) {
6101 .SUCCESS => {6087 .SUCCESS => {
6102 current_thread.endSyscall();6088 syscall.finish();
6103 return true;6089 return true;
6104 },6090 },
6105 .INTR => {6091 .INTR => {
6106 try current_thread.checkCancel();6092 try syscall.checkCancel();
6107 continue;6093 continue;
6108 },6094 },
6109 else => {6095 else => {
6110 current_thread.endSyscall();6096 syscall.finish();
6111 return false;6097 return false;
6112 },6098 },
6113 }6099 }
...@@ -6131,22 +6117,22 @@ fn isTty(current_thread: *Thread, file: File) Io.Cancelable!bool {...@@ -6131,22 +6117,22 @@ fn isTty(current_thread: *Thread, file: File) Io.Cancelable!bool {
61316117
6132 if (native_os == .linux) {6118 if (native_os == .linux) {
6133 const linux = std.os.linux;6119 const linux = std.os.linux;
6134 try current_thread.beginSyscall();6120 const syscall: Syscall = try .start();
6135 while (true) {6121 while (true) {
6136 var wsz: posix.winsize = undefined;6122 var wsz: posix.winsize = undefined;
6137 const fd: usize = @bitCast(@as(isize, file.handle));6123 const fd: usize = @bitCast(@as(isize, file.handle));
6138 const rc = linux.syscall3(.ioctl, fd, linux.T.IOCGWINSZ, @intFromPtr(&wsz));6124 const rc = linux.syscall3(.ioctl, fd, linux.T.IOCGWINSZ, @intFromPtr(&wsz));
6139 switch (linux.errno(rc)) {6125 switch (linux.errno(rc)) {
6140 .SUCCESS => {6126 .SUCCESS => {
6141 current_thread.endSyscall();6127 syscall.finish();
6142 return true;6128 return true;
6143 },6129 },
6144 .INTR => {6130 .INTR => {
6145 try current_thread.checkCancel();6131 try syscall.checkCancel();
6146 continue;6132 continue;
6147 },6133 },
6148 else => {6134 else => {
6149 current_thread.endSyscall();6135 syscall.finish();
6150 return false;6136 return false;
6151 },6137 },
6152 }6138 }
...@@ -6158,10 +6144,10 @@ fn isTty(current_thread: *Thread, file: File) Io.Cancelable!bool {...@@ -6158,10 +6144,10 @@ fn isTty(current_thread: *Thread, file: File) Io.Cancelable!bool {
61586144
6159fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiEscapeCodesError!void {6145fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiEscapeCodesError!void {
6160 const t: *Threaded = @ptrCast(@alignCast(userdata));6146 const t: *Threaded = @ptrCast(@alignCast(userdata));
6161 const current_thread = Thread.getCurrent(t);6147 _ = t;
61626148
6163 if (is_windows) {6149 if (is_windows) {
6164 try current_thread.checkCancel();6150 try Thread.checkCancel();
61656151
6166 // For Windows Terminal, VT Sequences processing is enabled by default.6152 // For Windows Terminal, VT Sequences processing is enabled by default.
6167 var original_console_mode: windows.DWORD = 0;6153 var original_console_mode: windows.DWORD = 0;
...@@ -6181,30 +6167,30 @@ fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiE...@@ -6181,30 +6167,30 @@ fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiE
6181 // we end up matching the mode of Windows Terminal.6167 // we end up matching the mode of Windows Terminal.
6182 const requested_console_modes = windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING;6168 const requested_console_modes = windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING;
6183 const console_mode = original_console_mode | requested_console_modes;6169 const console_mode = original_console_mode | requested_console_modes;
6184 try current_thread.checkCancel();6170 try Thread.checkCancel();
6185 if (windows.kernel32.SetConsoleMode(file.handle, console_mode) != 0) return;6171 if (windows.kernel32.SetConsoleMode(file.handle, console_mode) != 0) return;
6186 }6172 }
6187 if (try isCygwinPty(current_thread, file)) return;6173 if (try isCygwinPty(file)) return;
6188 } else {6174 } else {
6189 if (try supportsAnsiEscapeCodes(current_thread, file)) return;6175 if (try supportsAnsiEscapeCodes(file)) return;
6190 }6176 }
6191 return error.NotTerminalDevice;6177 return error.NotTerminalDevice;
6192}6178}
61936179
6194fn fileSupportsAnsiEscapeCodes(userdata: ?*anyopaque, file: File) Io.Cancelable!bool {6180fn fileSupportsAnsiEscapeCodes(userdata: ?*anyopaque, file: File) Io.Cancelable!bool {
6195 const t: *Threaded = @ptrCast(@alignCast(userdata));6181 const t: *Threaded = @ptrCast(@alignCast(userdata));
6196 const current_thread = Thread.getCurrent(t);6182 _ = t;
6197 return supportsAnsiEscapeCodes(current_thread, file);6183 return supportsAnsiEscapeCodes(file);
6198}6184}
61996185
6200fn supportsAnsiEscapeCodes(current_thread: *Thread, file: File) Io.Cancelable!bool {6186fn supportsAnsiEscapeCodes(file: File) Io.Cancelable!bool {
6201 if (is_windows) {6187 if (is_windows) {
6202 try current_thread.checkCancel();6188 try Thread.checkCancel();
6203 var console_mode: windows.DWORD = 0;6189 var console_mode: windows.DWORD = 0;
6204 if (windows.kernel32.GetConsoleMode(file.handle, &console_mode) != 0) {6190 if (windows.kernel32.GetConsoleMode(file.handle, &console_mode) != 0) {
6205 if (console_mode & windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0) return true;6191 if (console_mode & windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0) return true;
6206 }6192 }
6207 return isCygwinPty(current_thread, file);6193 return isCygwinPty(file);
6208 }6194 }
62096195
6210 if (native_os == .wasi) {6196 if (native_os == .wasi) {
...@@ -6214,12 +6200,12 @@ fn supportsAnsiEscapeCodes(current_thread: *Thread, file: File) Io.Cancelable!bo...@@ -6214,12 +6200,12 @@ fn supportsAnsiEscapeCodes(current_thread: *Thread, file: File) Io.Cancelable!bo
6214 return false;6200 return false;
6215 }6201 }
62166202
6217 if (try isTty(current_thread, file)) return true;6203 if (try isTty(file)) return true;
62186204
6219 return false;6205 return false;
6220}6206}
62216207
6222fn isCygwinPty(current_thread: *Thread, file: File) Io.Cancelable!bool {6208fn isCygwinPty(file: File) Io.Cancelable!bool {
6223 if (!is_windows) return false;6209 if (!is_windows) return false;
62246210
6225 const handle = file.handle;6211 const handle = file.handle;
...@@ -6234,7 +6220,7 @@ fn isCygwinPty(current_thread: *Thread, file: File) Io.Cancelable!bool {...@@ -6234,7 +6220,7 @@ fn isCygwinPty(current_thread: *Thread, file: File) Io.Cancelable!bool {
6234 // This allows us to avoid the more costly NtQueryInformationFile call6220 // This allows us to avoid the more costly NtQueryInformationFile call
6235 // for handles that aren't named pipes.6221 // for handles that aren't named pipes.
6236 {6222 {
6237 try current_thread.checkCancel();6223 try Thread.checkCancel();
6238 var io_status: windows.IO_STATUS_BLOCK = undefined;6224 var io_status: windows.IO_STATUS_BLOCK = undefined;
6239 var device_info: windows.FILE.FS_DEVICE_INFORMATION = undefined;6225 var device_info: windows.FILE.FS_DEVICE_INFORMATION = undefined;
6240 const rc = windows.ntdll.NtQueryVolumeInformationFile(6226 const rc = windows.ntdll.NtQueryVolumeInformationFile(
...@@ -6262,7 +6248,7 @@ fn isCygwinPty(current_thread: *Thread, file: File) Io.Cancelable!bool {...@@ -6262,7 +6248,7 @@ fn isCygwinPty(current_thread: *Thread, file: File) Io.Cancelable!bool {
6262 var name_info_bytes align(@alignOf(windows.FILE.NAME_INFORMATION)) = [_]u8{0} ** (name_bytes_offset + num_name_bytes);6248 var name_info_bytes align(@alignOf(windows.FILE.NAME_INFORMATION)) = [_]u8{0} ** (name_bytes_offset + num_name_bytes);
62636249
6264 var io_status_block: windows.IO_STATUS_BLOCK = undefined;6250 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
6265 try current_thread.checkCancel();6251 try Thread.checkCancel();
6266 const rc = windows.ntdll.NtQueryInformationFile(6252 const rc = windows.ntdll.NtQueryInformationFile(
6267 handle,6253 handle,
6268 &io_status_block,6254 &io_status_block,
...@@ -6287,13 +6273,13 @@ fn isCygwinPty(current_thread: *Thread, file: File) Io.Cancelable!bool {...@@ -6287,13 +6273,13 @@ fn isCygwinPty(current_thread: *Thread, file: File) Io.Cancelable!bool {
62876273
6288fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthError!void {6274fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthError!void {
6289 const t: *Threaded = @ptrCast(@alignCast(userdata));6275 const t: *Threaded = @ptrCast(@alignCast(userdata));
6290 const current_thread = Thread.getCurrent(t);6276 _ = t;
62916277
6292 const signed_len: i64 = @bitCast(length);6278 const signed_len: i64 = @bitCast(length);
6293 if (signed_len < 0) return error.FileTooBig; // Avoid ambiguous EINVAL errors.6279 if (signed_len < 0) return error.FileTooBig; // Avoid ambiguous EINVAL errors.
62946280
6295 if (is_windows) {6281 if (is_windows) {
6296 try current_thread.checkCancel();6282 try Thread.checkCancel();
62976283
6298 var io_status_block: windows.IO_STATUS_BLOCK = undefined;6284 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
6299 const eof_info: windows.FILE.END_OF_FILE_INFORMATION = .{6285 const eof_info: windows.FILE.END_OF_FILE_INFORMATION = .{
...@@ -6318,16 +6304,16 @@ fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthE...@@ -6318,16 +6304,16 @@ fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthE
6318 }6304 }
63196305
6320 if (native_os == .wasi and !builtin.link_libc) {6306 if (native_os == .wasi and !builtin.link_libc) {
6321 try current_thread.beginSyscall();6307 const syscall: Syscall = try .start();
6322 while (true) {6308 while (true) {
6323 switch (std.os.wasi.fd_filestat_set_size(file.handle, length)) {6309 switch (std.os.wasi.fd_filestat_set_size(file.handle, length)) {
6324 .SUCCESS => return current_thread.endSyscall(),6310 .SUCCESS => return syscall.finish(),
6325 .INTR => {6311 .INTR => {
6326 try current_thread.checkCancel();6312 try syscall.checkCancel();
6327 continue;6313 continue;
6328 },6314 },
6329 else => |e| {6315 else => |e| {
6330 current_thread.endSyscall();6316 syscall.finish();
6331 switch (e) {6317 switch (e) {
6332 .FBIG => return error.FileTooBig,6318 .FBIG => return error.FileTooBig,
6333 .IO => return error.InputOutput,6319 .IO => return error.InputOutput,
...@@ -6343,16 +6329,16 @@ fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthE...@@ -6343,16 +6329,16 @@ fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthE
6343 }6329 }
6344 }6330 }
63456331
6346 try current_thread.beginSyscall();6332 const syscall: Syscall = try .start();
6347 while (true) {6333 while (true) {
6348 switch (posix.errno(ftruncate_sym(file.handle, signed_len))) {6334 switch (posix.errno(ftruncate_sym(file.handle, signed_len))) {
6349 .SUCCESS => return current_thread.endSyscall(),6335 .SUCCESS => return syscall.finish(),
6350 .INTR => {6336 .INTR => {
6351 try current_thread.checkCancel();6337 try syscall.checkCancel();
6352 continue;6338 continue;
6353 },6339 },
6354 else => |e| {6340 else => |e| {
6355 current_thread.endSyscall();6341 syscall.finish();
6356 switch (e) {6342 switch (e) {
6357 .FBIG => return error.FileTooBig,6343 .FBIG => return error.FileTooBig,
6358 .IO => return error.InputOutput,6344 .IO => return error.InputOutput,
...@@ -6370,19 +6356,19 @@ fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthE...@@ -6370,19 +6356,19 @@ fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthE
6370fn fileSetOwner(userdata: ?*anyopaque, file: File, owner: ?File.Uid, group: ?File.Gid) File.SetOwnerError!void {6356fn fileSetOwner(userdata: ?*anyopaque, file: File, owner: ?File.Uid, group: ?File.Gid) File.SetOwnerError!void {
6371 if (!have_fchown) return error.Unexpected; // Unsupported OS, don't call this function.6357 if (!have_fchown) return error.Unexpected; // Unsupported OS, don't call this function.
6372 const t: *Threaded = @ptrCast(@alignCast(userdata));6358 const t: *Threaded = @ptrCast(@alignCast(userdata));
6373 const current_thread = Thread.getCurrent(t);6359 _ = t;
6374 const uid = owner orelse ~@as(posix.uid_t, 0);6360 const uid = owner orelse ~@as(posix.uid_t, 0);
6375 const gid = group orelse ~@as(posix.gid_t, 0);6361 const gid = group orelse ~@as(posix.gid_t, 0);
6376 return posixFchown(current_thread, file.handle, uid, gid);6362 return posixFchown(file.handle, uid, gid);
6377}6363}
63786364
6379fn fileSetPermissions(userdata: ?*anyopaque, file: File, permissions: File.Permissions) File.SetPermissionsError!void {6365fn fileSetPermissions(userdata: ?*anyopaque, file: File, permissions: File.Permissions) File.SetPermissionsError!void {
6380 if (@sizeOf(File.Permissions) == 0) return;6366 if (@sizeOf(File.Permissions) == 0) return;
6381 const t: *Threaded = @ptrCast(@alignCast(userdata));6367 const t: *Threaded = @ptrCast(@alignCast(userdata));
6382 const current_thread = Thread.getCurrent(t);6368 _ = t;
6383 switch (native_os) {6369 switch (native_os) {
6384 .windows => {6370 .windows => {
6385 try current_thread.checkCancel();6371 try Thread.checkCancel();
6386 var io_status_block: windows.IO_STATUS_BLOCK = undefined;6372 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
6387 const info: windows.FILE.BASIC_INFORMATION = .{6373 const info: windows.FILE.BASIC_INFORMATION = .{
6388 .CreationTime = 0,6374 .CreationTime = 0,
...@@ -6406,22 +6392,22 @@ fn fileSetPermissions(userdata: ?*anyopaque, file: File, permissions: File.Permi...@@ -6406,22 +6392,22 @@ fn fileSetPermissions(userdata: ?*anyopaque, file: File, permissions: File.Permi
6406 }6392 }
6407 },6393 },
6408 .wasi => return error.Unexpected, // Unsupported OS.6394 .wasi => return error.Unexpected, // Unsupported OS.
6409 else => return setPermissionsPosix(current_thread, file.handle, permissions.toMode()),6395 else => return setPermissionsPosix(file.handle, permissions.toMode()),
6410 }6396 }
6411}6397}
64126398
6413fn setPermissionsPosix(current_thread: *Thread, fd: posix.fd_t, mode: posix.mode_t) File.SetPermissionsError!void {6399fn setPermissionsPosix(fd: posix.fd_t, mode: posix.mode_t) File.SetPermissionsError!void {
6414 comptime assert(have_fchmod);6400 comptime assert(have_fchmod);
6415 try current_thread.beginSyscall();6401 const syscall: Syscall = try .start();
6416 while (true) {6402 while (true) {
6417 switch (posix.errno(posix.system.fchmod(fd, mode))) {6403 switch (posix.errno(posix.system.fchmod(fd, mode))) {
6418 .SUCCESS => return current_thread.endSyscall(),6404 .SUCCESS => return syscall.finish(),
6419 .INTR => {6405 .INTR => {
6420 try current_thread.checkCancel();6406 try syscall.checkCancel();
6421 continue;6407 continue;
6422 },6408 },
6423 else => |e| {6409 else => |e| {
6424 current_thread.endSyscall();6410 syscall.finish();
6425 switch (e) {6411 switch (e) {
6426 .BADF => |err| return errnoBug(err),6412 .BADF => |err| return errnoBug(err),
6427 .FAULT => |err| return errnoBug(err),6413 .FAULT => |err| return errnoBug(err),
...@@ -6448,7 +6434,7 @@ fn dirSetTimestamps(...@@ -6448,7 +6434,7 @@ fn dirSetTimestamps(
6448 options: Dir.SetTimestampsOptions,6434 options: Dir.SetTimestampsOptions,
6449) Dir.SetTimestampsError!void {6435) Dir.SetTimestampsError!void {
6450 const t: *Threaded = @ptrCast(@alignCast(userdata));6436 const t: *Threaded = @ptrCast(@alignCast(userdata));
6451 const current_thread = Thread.getCurrent(t);6437 _ = t;
64526438
6453 if (is_windows) {6439 if (is_windows) {
6454 @panic("TODO implement dirSetTimestamps windows");6440 @panic("TODO implement dirSetTimestamps windows");
...@@ -6472,20 +6458,20 @@ fn dirSetTimestamps(...@@ -6472,20 +6458,20 @@ fn dirSetTimestamps(
6472 var path_buffer: [posix.PATH_MAX]u8 = undefined;6458 var path_buffer: [posix.PATH_MAX]u8 = undefined;
6473 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);6459 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
64746460
6475 try current_thread.beginSyscall();6461 const syscall: Syscall = try .start();
6476 while (true) switch (posix.errno(posix.system.utimensat(dir.handle, sub_path_posix, times, flags))) {6462 while (true) switch (posix.errno(posix.system.utimensat(dir.handle, sub_path_posix, times, flags))) {
6477 .SUCCESS => return current_thread.endSyscall(),6463 .SUCCESS => return syscall.finish(),
6478 .INTR => {6464 .INTR => {
6479 try current_thread.checkCancel();6465 try syscall.checkCancel();
6480 continue;6466 continue;
6481 },6467 },
6482 .BADF => |err| return current_thread.endSyscallErrnoBug(err), // always a race condition6468 .BADF => |err| return syscall.errnoBug(err), // always a race condition
6483 .FAULT => |err| return current_thread.endSyscallErrnoBug(err),6469 .FAULT => |err| return syscall.errnoBug(err),
6484 .INVAL => |err| return current_thread.endSyscallErrnoBug(err),6470 .INVAL => |err| return syscall.errnoBug(err),
6485 .ACCES => return current_thread.endSyscallError(error.AccessDenied),6471 .ACCES => return syscall.fail(error.AccessDenied),
6486 .PERM => return current_thread.endSyscallError(error.PermissionDenied),6472 .PERM => return syscall.fail(error.PermissionDenied),
6487 .ROFS => return current_thread.endSyscallError(error.ReadOnlyFileSystem),6473 .ROFS => return syscall.fail(error.ReadOnlyFileSystem),
6488 else => |err| return current_thread.endSyscallUnexpectedErrno(err),6474 else => |err| return syscall.unexpectedErrno(err),
6489 };6475 };
6490}6476}
64916477
...@@ -6495,10 +6481,10 @@ fn fileSetTimestamps(...@@ -6495,10 +6481,10 @@ fn fileSetTimestamps(
6495 options: File.SetTimestampsOptions,6481 options: File.SetTimestampsOptions,
6496) File.SetTimestampsError!void {6482) File.SetTimestampsError!void {
6497 const t: *Threaded = @ptrCast(@alignCast(userdata));6483 const t: *Threaded = @ptrCast(@alignCast(userdata));
6498 const current_thread = Thread.getCurrent(t);6484 _ = t;
64996485
6500 if (is_windows) {6486 if (is_windows) {
6501 try current_thread.checkCancel();6487 try Thread.checkCancel();
65026488
6503 var access_time_buffer: windows.FILETIME = undefined;6489 var access_time_buffer: windows.FILETIME = undefined;
6504 var modify_time_buffer: windows.FILETIME = undefined;6490 var modify_time_buffer: windows.FILETIME = undefined;
...@@ -6559,20 +6545,20 @@ fn fileSetTimestamps(...@@ -6559,20 +6545,20 @@ fn fileSetTimestamps(
6559 },6545 },
6560 }6546 }
65616547
6562 try current_thread.beginSyscall();6548 const syscall: Syscall = try .start();
6563 while (true) switch (std.os.wasi.fd_filestat_set_times(file.handle, atime, mtime, flags)) {6549 while (true) switch (std.os.wasi.fd_filestat_set_times(file.handle, atime, mtime, flags)) {
6564 .SUCCESS => return current_thread.endSyscall(),6550 .SUCCESS => return syscall.finish(),
6565 .INTR => {6551 .INTR => {
6566 try current_thread.checkCancel();6552 try syscall.checkCancel();
6567 continue;6553 continue;
6568 },6554 },
6569 .BADF => |err| return current_thread.endSyscallErrnoBug(err), // File descriptor use-after-free.6555 .BADF => |err| return syscall.errnoBug(err), // File descriptor use-after-free.
6570 .FAULT => |err| return current_thread.endSyscallErrnoBug(err),6556 .FAULT => |err| return syscall.errnoBug(err),
6571 .INVAL => |err| return current_thread.endSyscallErrnoBug(err),6557 .INVAL => |err| return syscall.errnoBug(err),
6572 .ACCES => return current_thread.endSyscallError(error.AccessDenied),6558 .ACCES => return syscall.fail(error.AccessDenied),
6573 .PERM => return current_thread.endSyscallError(error.PermissionDenied),6559 .PERM => return syscall.fail(error.PermissionDenied),
6574 .ROFS => return current_thread.endSyscallError(error.ReadOnlyFileSystem),6560 .ROFS => return syscall.fail(error.ReadOnlyFileSystem),
6575 else => |err| return current_thread.endSyscallUnexpectedErrno(err),6561 else => |err| return syscall.unexpectedErrno(err),
6576 };6562 };
6577 }6563 }
65786564
...@@ -6585,20 +6571,20 @@ fn fileSetTimestamps(...@@ -6585,20 +6571,20 @@ fn fileSetTimestamps(
6585 break :p &times_buffer;6571 break :p &times_buffer;
6586 };6572 };
65876573
6588 try current_thread.beginSyscall();6574 const syscall: Syscall = try .start();
6589 while (true) switch (posix.errno(posix.system.futimens(file.handle, times))) {6575 while (true) switch (posix.errno(posix.system.futimens(file.handle, times))) {
6590 .SUCCESS => return current_thread.endSyscall(),6576 .SUCCESS => return syscall.finish(),
6591 .INTR => {6577 .INTR => {
6592 try current_thread.checkCancel();6578 try syscall.checkCancel();
6593 continue;6579 continue;
6594 },6580 },
6595 .BADF => |err| return current_thread.endSyscallErrnoBug(err), // always a race condition6581 .BADF => |err| return syscall.errnoBug(err), // always a race condition
6596 .FAULT => |err| return current_thread.endSyscallErrnoBug(err),6582 .FAULT => |err| return syscall.errnoBug(err),
6597 .INVAL => |err| return current_thread.endSyscallErrnoBug(err),6583 .INVAL => |err| return syscall.errnoBug(err),
6598 .ACCES => return current_thread.endSyscallError(error.AccessDenied),6584 .ACCES => return syscall.fail(error.AccessDenied),
6599 .PERM => return current_thread.endSyscallError(error.PermissionDenied),6585 .PERM => return syscall.fail(error.PermissionDenied),
6600 .ROFS => return current_thread.endSyscallError(error.ReadOnlyFileSystem),6586 .ROFS => return syscall.fail(error.ReadOnlyFileSystem),
6601 else => |err| return current_thread.endSyscallUnexpectedErrno(err),6587 else => |err| return syscall.unexpectedErrno(err),
6602 };6588 };
6603}6589}
66046590
...@@ -6608,7 +6594,7 @@ const windows_lock_range_len: windows.LARGE_INTEGER = 1;...@@ -6608,7 +6594,7 @@ const windows_lock_range_len: windows.LARGE_INTEGER = 1;
6608fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!void {6594fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!void {
6609 if (native_os == .wasi) return error.FileLocksUnsupported;6595 if (native_os == .wasi) return error.FileLocksUnsupported;
6610 const t: *Threaded = @ptrCast(@alignCast(userdata));6596 const t: *Threaded = @ptrCast(@alignCast(userdata));
6611 const current_thread = Thread.getCurrent(t);6597 _ = t;
66126598
6613 if (is_windows) {6599 if (is_windows) {
6614 const exclusive = switch (lock) {6600 const exclusive = switch (lock) {
...@@ -6633,7 +6619,7 @@ fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!v...@@ -6633,7 +6619,7 @@ fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!v
6633 .shared => false,6619 .shared => false,
6634 .exclusive => true,6620 .exclusive => true,
6635 };6621 };
6636 try current_thread.checkCancel();6622 try Thread.checkCancel();
6637 var io_status_block: windows.IO_STATUS_BLOCK = undefined;6623 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
6638 const status = windows.ntdll.NtLockFile(6624 const status = windows.ntdll.NtLockFile(
6639 file.handle,6625 file.handle,
...@@ -6661,16 +6647,16 @@ fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!v...@@ -6661,16 +6647,16 @@ fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!v
6661 .shared => posix.LOCK.SH,6647 .shared => posix.LOCK.SH,
6662 .exclusive => posix.LOCK.EX,6648 .exclusive => posix.LOCK.EX,
6663 };6649 };
6664 try current_thread.beginSyscall();6650 const syscall: Syscall = try .start();
6665 while (true) {6651 while (true) {
6666 switch (posix.errno(posix.system.flock(file.handle, operation))) {6652 switch (posix.errno(posix.system.flock(file.handle, operation))) {
6667 .SUCCESS => return current_thread.endSyscall(),6653 .SUCCESS => return syscall.finish(),
6668 .INTR => {6654 .INTR => {
6669 try current_thread.checkCancel();6655 try syscall.checkCancel();
6670 continue;6656 continue;
6671 },6657 },
6672 else => |e| {6658 else => |e| {
6673 current_thread.endSyscall();6659 syscall.finish();
6674 switch (e) {6660 switch (e) {
6675 .BADF => |err| return errnoBug(err),6661 .BADF => |err| return errnoBug(err),
6676 .INVAL => |err| return errnoBug(err), // invalid parameters6662 .INVAL => |err| return errnoBug(err), // invalid parameters
...@@ -6687,7 +6673,7 @@ fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!v...@@ -6687,7 +6673,7 @@ fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!v
6687fn fileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!bool {6673fn fileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!bool {
6688 if (native_os == .wasi) return error.FileLocksUnsupported;6674 if (native_os == .wasi) return error.FileLocksUnsupported;
6689 const t: *Threaded = @ptrCast(@alignCast(userdata));6675 const t: *Threaded = @ptrCast(@alignCast(userdata));
6690 const current_thread = Thread.getCurrent(t);6676 _ = t;
66916677
6692 if (is_windows) {6678 if (is_windows) {
6693 const exclusive = switch (lock) {6679 const exclusive = switch (lock) {
...@@ -6711,7 +6697,7 @@ fn fileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockErro...@@ -6711,7 +6697,7 @@ fn fileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockErro
6711 .shared => false,6697 .shared => false,
6712 .exclusive => true,6698 .exclusive => true,
6713 };6699 };
6714 try current_thread.checkCancel();6700 try Thread.checkCancel();
6715 var io_status_block: windows.IO_STATUS_BLOCK = undefined;6701 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
6716 const status = windows.ntdll.NtLockFile(6702 const status = windows.ntdll.NtLockFile(
6717 file.handle,6703 file.handle,
...@@ -6739,23 +6725,23 @@ fn fileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockErro...@@ -6739,23 +6725,23 @@ fn fileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockErro
6739 .shared => posix.LOCK.SH | posix.LOCK.NB,6725 .shared => posix.LOCK.SH | posix.LOCK.NB,
6740 .exclusive => posix.LOCK.EX | posix.LOCK.NB,6726 .exclusive => posix.LOCK.EX | posix.LOCK.NB,
6741 };6727 };
6742 try current_thread.beginSyscall();6728 const syscall: Syscall = try .start();
6743 while (true) {6729 while (true) {
6744 switch (posix.errno(posix.system.flock(file.handle, operation))) {6730 switch (posix.errno(posix.system.flock(file.handle, operation))) {
6745 .SUCCESS => {6731 .SUCCESS => {
6746 current_thread.endSyscall();6732 syscall.finish();
6747 return true;6733 return true;
6748 },6734 },
6749 .INTR => {6735 .INTR => {
6750 try current_thread.checkCancel();6736 try syscall.checkCancel();
6751 continue;6737 continue;
6752 },6738 },
6753 .AGAIN => {6739 .AGAIN => {
6754 current_thread.endSyscall();6740 syscall.finish();
6755 return false;6741 return false;
6756 },6742 },
6757 else => |e| {6743 else => |e| {
6758 current_thread.endSyscall();6744 syscall.finish();
6759 switch (e) {6745 switch (e) {
6760 .BADF => |err| return errnoBug(err),6746 .BADF => |err| return errnoBug(err),
6761 .INVAL => |err| return errnoBug(err), // invalid parameters6747 .INVAL => |err| return errnoBug(err), // invalid parameters
...@@ -6808,10 +6794,10 @@ fn fileUnlock(userdata: ?*anyopaque, file: File) void {...@@ -6808,10 +6794,10 @@ fn fileUnlock(userdata: ?*anyopaque, file: File) void {
6808fn fileDowngradeLock(userdata: ?*anyopaque, file: File) File.DowngradeLockError!void {6794fn fileDowngradeLock(userdata: ?*anyopaque, file: File) File.DowngradeLockError!void {
6809 if (native_os == .wasi) return;6795 if (native_os == .wasi) return;
6810 const t: *Threaded = @ptrCast(@alignCast(userdata));6796 const t: *Threaded = @ptrCast(@alignCast(userdata));
6811 const current_thread = Thread.getCurrent(t);6797 _ = t;
68126798
6813 if (is_windows) {6799 if (is_windows) {
6814 try current_thread.checkCancel();6800 try Thread.checkCancel();
6815 // On Windows it works like a semaphore + exclusivity flag. To6801 // On Windows it works like a semaphore + exclusivity flag. To
6816 // implement this function, we first obtain another lock in shared6802 // implement this function, we first obtain another lock in shared
6817 // mode. This changes the exclusivity flag, but increments the6803 // mode. This changes the exclusivity flag, but increments the
...@@ -6854,19 +6840,19 @@ fn fileDowngradeLock(userdata: ?*anyopaque, file: File) File.DowngradeLockError!...@@ -6854,19 +6840,19 @@ fn fileDowngradeLock(userdata: ?*anyopaque, file: File) File.DowngradeLockError!
68546840
6855 const operation = posix.LOCK.SH | posix.LOCK.NB;6841 const operation = posix.LOCK.SH | posix.LOCK.NB;
68566842
6857 try current_thread.beginSyscall();6843 const syscall: Syscall = try .start();
6858 while (true) {6844 while (true) {
6859 switch (posix.errno(posix.system.flock(file.handle, operation))) {6845 switch (posix.errno(posix.system.flock(file.handle, operation))) {
6860 .SUCCESS => {6846 .SUCCESS => {
6861 current_thread.endSyscall();6847 syscall.finish();
6862 return;6848 return;
6863 },6849 },
6864 .INTR => {6850 .INTR => {
6865 try current_thread.checkCancel();6851 try syscall.checkCancel();
6866 continue;6852 continue;
6867 },6853 },
6868 else => |e| {6854 else => |e| {
6869 current_thread.endSyscall();6855 syscall.finish();
6870 switch (e) {6856 switch (e) {
6871 .AGAIN => |err| return errnoBug(err), // File was not locked in exclusive mode.6857 .AGAIN => |err| return errnoBug(err), // File was not locked in exclusive mode.
6872 .BADF => |err| return errnoBug(err),6858 .BADF => |err| return errnoBug(err),
...@@ -6888,7 +6874,7 @@ fn dirOpenDirWasi(...@@ -6888,7 +6874,7 @@ fn dirOpenDirWasi(
6888) Dir.OpenError!Dir {6874) Dir.OpenError!Dir {
6889 if (builtin.link_libc) return dirOpenDirPosix(userdata, dir, sub_path, options);6875 if (builtin.link_libc) return dirOpenDirPosix(userdata, dir, sub_path, options);
6890 const t: *Threaded = @ptrCast(@alignCast(userdata));6876 const t: *Threaded = @ptrCast(@alignCast(userdata));
6891 const current_thread = Thread.getCurrent(t);6877 _ = t;
6892 const wasi = std.os.wasi;6878 const wasi = std.os.wasi;
68936879
6894 var base: std.os.wasi.rights_t = .{6880 var base: std.os.wasi.rights_t = .{
...@@ -6918,19 +6904,19 @@ fn dirOpenDirWasi(...@@ -6918,19 +6904,19 @@ fn dirOpenDirWasi(
6918 const oflags: wasi.oflags_t = .{ .DIRECTORY = true };6904 const oflags: wasi.oflags_t = .{ .DIRECTORY = true };
6919 const fdflags: wasi.fdflags_t = .{};6905 const fdflags: wasi.fdflags_t = .{};
6920 var fd: posix.fd_t = undefined;6906 var fd: posix.fd_t = undefined;
6921 try current_thread.beginSyscall();6907 const syscall: Syscall = try .start();
6922 while (true) {6908 while (true) {
6923 switch (wasi.path_open(dir.handle, lookup_flags, sub_path.ptr, sub_path.len, oflags, base, base, fdflags, &fd)) {6909 switch (wasi.path_open(dir.handle, lookup_flags, sub_path.ptr, sub_path.len, oflags, base, base, fdflags, &fd)) {
6924 .SUCCESS => {6910 .SUCCESS => {
6925 current_thread.endSyscall();6911 syscall.finish();
6926 return .{ .handle = fd };6912 return .{ .handle = fd };
6927 },6913 },
6928 .INTR => {6914 .INTR => {
6929 try current_thread.checkCancel();6915 try syscall.checkCancel();
6930 continue;6916 continue;
6931 },6917 },
6932 else => |e| {6918 else => |e| {
6933 current_thread.endSyscall();6919 syscall.finish();
6934 switch (e) {6920 switch (e) {
6935 .FAULT => |err| return errnoBug(err),6921 .FAULT => |err| return errnoBug(err),
6936 .INVAL => return error.BadPathName,6922 .INVAL => return error.BadPathName,
...@@ -6965,13 +6951,13 @@ fn dirHardLink(...@@ -6965,13 +6951,13 @@ fn dirHardLink(
6965) Dir.HardLinkError!void {6951) Dir.HardLinkError!void {
6966 if (is_windows) return error.OperationUnsupported;6952 if (is_windows) return error.OperationUnsupported;
6967 const t: *Threaded = @ptrCast(@alignCast(userdata));6953 const t: *Threaded = @ptrCast(@alignCast(userdata));
6968 const current_thread = Thread.getCurrent(t);6954 _ = t;
69696955
6970 if (native_os == .wasi and !builtin.link_libc) {6956 if (native_os == .wasi and !builtin.link_libc) {
6971 const flags: std.os.wasi.lookupflags_t = .{6957 const flags: std.os.wasi.lookupflags_t = .{
6972 .SYMLINK_FOLLOW = options.follow_symlinks,6958 .SYMLINK_FOLLOW = options.follow_symlinks,
6973 };6959 };
6974 try current_thread.beginSyscall();6960 const syscall: Syscall = try .start();
6975 while (true) {6961 while (true) {
6976 switch (std.os.wasi.path_link(6962 switch (std.os.wasi.path_link(
6977 old_dir.handle,6963 old_dir.handle,
...@@ -6982,13 +6968,13 @@ fn dirHardLink(...@@ -6982,13 +6968,13 @@ fn dirHardLink(
6982 new_sub_path.ptr,6968 new_sub_path.ptr,
6983 new_sub_path.len,6969 new_sub_path.len,
6984 )) {6970 )) {
6985 .SUCCESS => return current_thread.endSyscall(),6971 .SUCCESS => return syscall.finish(),
6986 .INTR => {6972 .INTR => {
6987 try current_thread.checkCancel();6973 try syscall.checkCancel();
6988 continue;6974 continue;
6989 },6975 },
6990 else => |e| {6976 else => |e| {
6991 current_thread.endSyscall();6977 syscall.finish();
6992 switch (e) {6978 switch (e) {
6993 .ACCES => return error.AccessDenied,6979 .ACCES => return error.AccessDenied,
6994 .DQUOT => return error.DiskQuota,6980 .DQUOT => return error.DiskQuota,
...@@ -7022,7 +7008,7 @@ fn dirHardLink(...@@ -7022,7 +7008,7 @@ fn dirHardLink(
70227008
7023 const flags: u32 = if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0;7009 const flags: u32 = if (!options.follow_symlinks) posix.AT.SYMLINK_NOFOLLOW else 0;
70247010
7025 try current_thread.beginSyscall();7011 const syscall: Syscall = try .start();
7026 while (true) {7012 while (true) {
7027 switch (posix.errno(posix.system.linkat(7013 switch (posix.errno(posix.system.linkat(
7028 old_dir.handle,7014 old_dir.handle,
...@@ -7031,13 +7017,13 @@ fn dirHardLink(...@@ -7031,13 +7017,13 @@ fn dirHardLink(
7031 new_sub_path_posix,7017 new_sub_path_posix,
7032 flags,7018 flags,
7033 ))) {7019 ))) {
7034 .SUCCESS => return current_thread.endSyscall(),7020 .SUCCESS => return syscall.finish(),
7035 .INTR => {7021 .INTR => {
7036 try current_thread.checkCancel();7022 try syscall.checkCancel();
7037 continue;7023 continue;
7038 },7024 },
7039 else => |e| {7025 else => |e| {
7040 current_thread.endSyscall();7026 syscall.finish();
7041 switch (e) {7027 switch (e) {
7042 .ACCES => return error.AccessDenied,7028 .ACCES => return error.AccessDenied,
7043 .DQUOT => return error.DiskQuota,7029 .DQUOT => return error.DiskQuota,
...@@ -7076,7 +7062,7 @@ const fileReadStreaming = switch (native_os) {...@@ -7076,7 +7062,7 @@ const fileReadStreaming = switch (native_os) {
70767062
7077fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8) File.Reader.Error!usize {7063fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8) File.Reader.Error!usize {
7078 const t: *Threaded = @ptrCast(@alignCast(userdata));7064 const t: *Threaded = @ptrCast(@alignCast(userdata));
7079 const current_thread = Thread.getCurrent(t);7065 _ = t;
70807066
7081 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;7067 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;
7082 var i: usize = 0;7068 var i: usize = 0;
...@@ -7092,20 +7078,20 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)...@@ -7092,20 +7078,20 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)
7092 assert(dest[0].len > 0);7078 assert(dest[0].len > 0);
70937079
7094 if (native_os == .wasi and !builtin.link_libc) {7080 if (native_os == .wasi and !builtin.link_libc) {
7095 try current_thread.beginSyscall();7081 const syscall: Syscall = try .start();
7096 while (true) {7082 while (true) {
7097 var nread: usize = undefined;7083 var nread: usize = undefined;
7098 switch (std.os.wasi.fd_read(file.handle, dest.ptr, dest.len, &nread)) {7084 switch (std.os.wasi.fd_read(file.handle, dest.ptr, dest.len, &nread)) {
7099 .SUCCESS => {7085 .SUCCESS => {
7100 current_thread.endSyscall();7086 syscall.finish();
7101 return nread;7087 return nread;
7102 },7088 },
7103 .INTR => {7089 .INTR => {
7104 try current_thread.checkCancel();7090 try syscall.checkCancel();
7105 continue;7091 continue;
7106 },7092 },
7107 else => |e| {7093 else => |e| {
7108 current_thread.endSyscall();7094 syscall.finish();
7109 switch (e) {7095 switch (e) {
7110 .INVAL => |err| return errnoBug(err),7096 .INVAL => |err| return errnoBug(err),
7111 .FAULT => |err| return errnoBug(err),7097 .FAULT => |err| return errnoBug(err),
...@@ -7125,20 +7111,20 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)...@@ -7125,20 +7111,20 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)
7125 }7111 }
7126 }7112 }
71277113
7128 try current_thread.beginSyscall();7114 const syscall: Syscall = try .start();
7129 while (true) {7115 while (true) {
7130 const rc = posix.system.readv(file.handle, dest.ptr, @intCast(dest.len));7116 const rc = posix.system.readv(file.handle, dest.ptr, @intCast(dest.len));
7131 switch (posix.errno(rc)) {7117 switch (posix.errno(rc)) {
7132 .SUCCESS => {7118 .SUCCESS => {
7133 current_thread.endSyscall();7119 syscall.finish();
7134 return @intCast(rc);7120 return @intCast(rc);
7135 },7121 },
7136 .INTR => {7122 .INTR => {
7137 try current_thread.checkCancel();7123 try syscall.checkCancel();
7138 continue;7124 continue;
7139 },7125 },
7140 else => |e| {7126 else => |e| {
7141 current_thread.endSyscall();7127 syscall.finish();
7142 switch (e) {7128 switch (e) {
7143 .INVAL => |err| return errnoBug(err),7129 .INVAL => |err| return errnoBug(err),
7144 .FAULT => |err| return errnoBug(err),7130 .FAULT => |err| return errnoBug(err),
...@@ -7163,7 +7149,7 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)...@@ -7163,7 +7149,7 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)
71637149
7164fn fileReadStreamingWindows(userdata: ?*anyopaque, file: File, data: []const []u8) File.Reader.Error!usize {7150fn fileReadStreamingWindows(userdata: ?*anyopaque, file: File, data: []const []u8) File.Reader.Error!usize {
7165 const t: *Threaded = @ptrCast(@alignCast(userdata));7151 const t: *Threaded = @ptrCast(@alignCast(userdata));
7166 const current_thread = Thread.getCurrent(t);7152 _ = t;
71677153
7168 const DWORD = windows.DWORD;7154 const DWORD = windows.DWORD;
7169 var index: usize = 0;7155 var index: usize = 0;
...@@ -7173,7 +7159,7 @@ fn fileReadStreamingWindows(userdata: ?*anyopaque, file: File, data: []const []u...@@ -7173,7 +7159,7 @@ fn fileReadStreamingWindows(userdata: ?*anyopaque, file: File, data: []const []u
7173 const want_read_count: DWORD = @min(std.math.maxInt(DWORD), buffer.len);7159 const want_read_count: DWORD = @min(std.math.maxInt(DWORD), buffer.len);
71747160
7175 while (true) {7161 while (true) {
7176 try current_thread.checkCancel();7162 try Thread.checkCancel();
7177 var n: DWORD = undefined;7163 var n: DWORD = undefined;
7178 if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, null) != 0)7164 if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, null) != 0)
7179 return n;7165 return n;
...@@ -7193,7 +7179,7 @@ fn fileReadStreamingWindows(userdata: ?*anyopaque, file: File, data: []const []u...@@ -7193,7 +7179,7 @@ fn fileReadStreamingWindows(userdata: ?*anyopaque, file: File, data: []const []u
71937179
7194fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8, offset: u64) File.ReadPositionalError!usize {7180fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8, offset: u64) File.ReadPositionalError!usize {
7195 const t: *Threaded = @ptrCast(@alignCast(userdata));7181 const t: *Threaded = @ptrCast(@alignCast(userdata));
7196 const current_thread = Thread.getCurrent(t);7182 _ = t;
71977183
7198 if (!have_preadv) @compileError("TODO implement fileReadPositionalPosix for cursed operating systems that don't support preadv (it's only Haiku)");7184 if (!have_preadv) @compileError("TODO implement fileReadPositionalPosix for cursed operating systems that don't support preadv (it's only Haiku)");
71997185
...@@ -7211,20 +7197,20 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8...@@ -7211,20 +7197,20 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8
7211 assert(dest[0].len > 0);7197 assert(dest[0].len > 0);
72127198
7213 if (native_os == .wasi and !builtin.link_libc) {7199 if (native_os == .wasi and !builtin.link_libc) {
7214 try current_thread.beginSyscall();7200 const syscall: Syscall = try .start();
7215 while (true) {7201 while (true) {
7216 var nread: usize = undefined;7202 var nread: usize = undefined;
7217 switch (std.os.wasi.fd_pread(file.handle, dest.ptr, dest.len, offset, &nread)) {7203 switch (std.os.wasi.fd_pread(file.handle, dest.ptr, dest.len, offset, &nread)) {
7218 .SUCCESS => {7204 .SUCCESS => {
7219 current_thread.endSyscall();7205 syscall.finish();
7220 return nread;7206 return nread;
7221 },7207 },
7222 .INTR => {7208 .INTR => {
7223 try current_thread.checkCancel();7209 try syscall.checkCancel();
7224 continue;7210 continue;
7225 },7211 },
7226 else => |e| {7212 else => |e| {
7227 current_thread.endSyscall();7213 syscall.finish();
7228 switch (e) {7214 switch (e) {
7229 .INVAL => |err| return errnoBug(err),7215 .INVAL => |err| return errnoBug(err),
7230 .FAULT => |err| return errnoBug(err),7216 .FAULT => |err| return errnoBug(err),
...@@ -7248,20 +7234,20 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8...@@ -7248,20 +7234,20 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8
7248 }7234 }
7249 }7235 }
72507236
7251 try current_thread.beginSyscall();7237 const syscall: Syscall = try .start();
7252 while (true) {7238 while (true) {
7253 const rc = preadv_sym(file.handle, dest.ptr, @intCast(dest.len), @bitCast(offset));7239 const rc = preadv_sym(file.handle, dest.ptr, @intCast(dest.len), @bitCast(offset));
7254 switch (posix.errno(rc)) {7240 switch (posix.errno(rc)) {
7255 .SUCCESS => {7241 .SUCCESS => {
7256 current_thread.endSyscall();7242 syscall.finish();
7257 return @bitCast(rc);7243 return @bitCast(rc);
7258 },7244 },
7259 .INTR => {7245 .INTR => {
7260 try current_thread.checkCancel();7246 try syscall.checkCancel();
7261 continue;7247 continue;
7262 },7248 },
7263 else => |e| {7249 else => |e| {
7264 current_thread.endSyscall();7250 syscall.finish();
7265 switch (e) {7251 switch (e) {
7266 .INVAL => |err| return errnoBug(err),7252 .INVAL => |err| return errnoBug(err),
7267 .FAULT => |err| return errnoBug(err),7253 .FAULT => |err| return errnoBug(err),
...@@ -7294,7 +7280,7 @@ const fileReadPositional = switch (native_os) {...@@ -7294,7 +7280,7 @@ const fileReadPositional = switch (native_os) {
72947280
7295fn fileReadPositionalWindows(userdata: ?*anyopaque, file: File, data: []const []u8, offset: u64) File.ReadPositionalError!usize {7281fn fileReadPositionalWindows(userdata: ?*anyopaque, file: File, data: []const []u8, offset: u64) File.ReadPositionalError!usize {
7296 const t: *Threaded = @ptrCast(@alignCast(userdata));7282 const t: *Threaded = @ptrCast(@alignCast(userdata));
7297 const current_thread = Thread.getCurrent(t);7283 _ = t;
72987284
7299 const DWORD = windows.DWORD;7285 const DWORD = windows.DWORD;
73007286
...@@ -7317,7 +7303,7 @@ fn fileReadPositionalWindows(userdata: ?*anyopaque, file: File, data: []const []...@@ -7317,7 +7303,7 @@ fn fileReadPositionalWindows(userdata: ?*anyopaque, file: File, data: []const []
7317 };7303 };
73187304
7319 while (true) {7305 while (true) {
7320 try current_thread.checkCancel();7306 try Thread.checkCancel();
7321 var n: DWORD = undefined;7307 var n: DWORD = undefined;
7322 if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, &overlapped) != 0)7308 if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, &overlapped) != 0)
7323 return n;7309 return n;
...@@ -7337,24 +7323,24 @@ fn fileReadPositionalWindows(userdata: ?*anyopaque, file: File, data: []const []...@@ -7337,24 +7323,24 @@ fn fileReadPositionalWindows(userdata: ?*anyopaque, file: File, data: []const []
73377323
7338fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!void {7324fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!void {
7339 const t: *Threaded = @ptrCast(@alignCast(userdata));7325 const t: *Threaded = @ptrCast(@alignCast(userdata));
7340 const current_thread = Thread.getCurrent(t);7326 _ = t;
7341 const fd = file.handle;7327 const fd = file.handle;
73427328
7343 if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {7329 if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
7344 var result: u64 = undefined;7330 var result: u64 = undefined;
7345 try current_thread.beginSyscall();7331 const syscall: Syscall = try .start();
7346 while (true) {7332 while (true) {
7347 switch (posix.errno(posix.system.llseek(fd, @bitCast(offset), &result, posix.SEEK.CUR))) {7333 switch (posix.errno(posix.system.llseek(fd, @bitCast(offset), &result, posix.SEEK.CUR))) {
7348 .SUCCESS => {7334 .SUCCESS => {
7349 current_thread.endSyscall();7335 syscall.finish();
7350 return;7336 return;
7351 },7337 },
7352 .INTR => {7338 .INTR => {
7353 try current_thread.checkCancel();7339 try syscall.checkCancel();
7354 continue;7340 continue;
7355 },7341 },
7356 else => |e| {7342 else => |e| {
7357 current_thread.endSyscall();7343 syscall.finish();
7358 switch (e) {7344 switch (e) {
7359 .BADF => |err| return errnoBug(err), // File descriptor used after closed.7345 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
7360 .INVAL => return error.Unseekable,7346 .INVAL => return error.Unseekable,
...@@ -7369,25 +7355,25 @@ fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!voi...@@ -7369,25 +7355,25 @@ fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!voi
7369 }7355 }
73707356
7371 if (native_os == .windows) {7357 if (native_os == .windows) {
7372 try current_thread.checkCancel();7358 try Thread.checkCancel();
7373 return windows.SetFilePointerEx_CURRENT(fd, offset);7359 return windows.SetFilePointerEx_CURRENT(fd, offset);
7374 }7360 }
73757361
7376 if (native_os == .wasi and !builtin.link_libc) {7362 if (native_os == .wasi and !builtin.link_libc) {
7377 var new_offset: std.os.wasi.filesize_t = undefined;7363 var new_offset: std.os.wasi.filesize_t = undefined;
7378 try current_thread.beginSyscall();7364 const syscall: Syscall = try .start();
7379 while (true) {7365 while (true) {
7380 switch (std.os.wasi.fd_seek(fd, offset, .CUR, &new_offset)) {7366 switch (std.os.wasi.fd_seek(fd, offset, .CUR, &new_offset)) {
7381 .SUCCESS => {7367 .SUCCESS => {
7382 current_thread.endSyscall();7368 syscall.finish();
7383 return;7369 return;
7384 },7370 },
7385 .INTR => {7371 .INTR => {
7386 try current_thread.checkCancel();7372 try syscall.checkCancel();
7387 continue;7373 continue;
7388 },7374 },
7389 else => |e| {7375 else => |e| {
7390 current_thread.endSyscall();7376 syscall.finish();
7391 switch (e) {7377 switch (e) {
7392 .BADF => |err| return errnoBug(err), // File descriptor used after closed.7378 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
7393 .INVAL => return error.Unseekable,7379 .INVAL => return error.Unseekable,
...@@ -7404,19 +7390,19 @@ fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!voi...@@ -7404,19 +7390,19 @@ fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!voi
74047390
7405 if (posix.SEEK == void) return error.Unseekable;7391 if (posix.SEEK == void) return error.Unseekable;
74067392
7407 try current_thread.beginSyscall();7393 const syscall: Syscall = try .start();
7408 while (true) {7394 while (true) {
7409 switch (posix.errno(lseek_sym(fd, offset, posix.SEEK.CUR))) {7395 switch (posix.errno(lseek_sym(fd, offset, posix.SEEK.CUR))) {
7410 .SUCCESS => {7396 .SUCCESS => {
7411 current_thread.endSyscall();7397 syscall.finish();
7412 return;7398 return;
7413 },7399 },
7414 .INTR => {7400 .INTR => {
7415 try current_thread.checkCancel();7401 try syscall.checkCancel();
7416 continue;7402 continue;
7417 },7403 },
7418 else => |e| {7404 else => |e| {
7419 current_thread.endSyscall();7405 syscall.finish();
7420 switch (e) {7406 switch (e) {
7421 .BADF => |err| return errnoBug(err), // File descriptor used after closed.7407 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
7422 .INVAL => return error.Unseekable,7408 .INVAL => return error.Unseekable,
...@@ -7432,29 +7418,29 @@ fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!voi...@@ -7432,29 +7418,29 @@ fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!voi
74327418
7433fn fileSeekTo(userdata: ?*anyopaque, file: File, offset: u64) File.SeekError!void {7419fn fileSeekTo(userdata: ?*anyopaque, file: File, offset: u64) File.SeekError!void {
7434 const t: *Threaded = @ptrCast(@alignCast(userdata));7420 const t: *Threaded = @ptrCast(@alignCast(userdata));
7435 const current_thread = Thread.getCurrent(t);7421 _ = t;
7436 const fd = file.handle;7422 const fd = file.handle;
74377423
7438 if (native_os == .windows) {7424 if (native_os == .windows) {
7439 try current_thread.checkCancel();7425 try Thread.checkCancel();
7440 return windows.SetFilePointerEx_BEGIN(fd, offset);7426 return windows.SetFilePointerEx_BEGIN(fd, offset);
7441 }7427 }
74427428
7443 if (native_os == .wasi and !builtin.link_libc) {7429 if (native_os == .wasi and !builtin.link_libc) {
7444 try current_thread.beginSyscall();7430 const syscall: Syscall = try .start();
7445 while (true) {7431 while (true) {
7446 var new_offset: std.os.wasi.filesize_t = undefined;7432 var new_offset: std.os.wasi.filesize_t = undefined;
7447 switch (std.os.wasi.fd_seek(fd, @bitCast(offset), .SET, &new_offset)) {7433 switch (std.os.wasi.fd_seek(fd, @bitCast(offset), .SET, &new_offset)) {
7448 .SUCCESS => {7434 .SUCCESS => {
7449 current_thread.endSyscall();7435 syscall.finish();
7450 return;7436 return;
7451 },7437 },
7452 .INTR => {7438 .INTR => {
7453 try current_thread.checkCancel();7439 try syscall.checkCancel();
7454 continue;7440 continue;
7455 },7441 },
7456 else => |e| {7442 else => |e| {
7457 current_thread.endSyscall();7443 syscall.finish();
7458 switch (e) {7444 switch (e) {
7459 .BADF => |err| return errnoBug(err), // File descriptor used after closed.7445 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
7460 .INVAL => return error.Unseekable,7446 .INVAL => return error.Unseekable,
...@@ -7471,25 +7457,25 @@ fn fileSeekTo(userdata: ?*anyopaque, file: File, offset: u64) File.SeekError!voi...@@ -7471,25 +7457,25 @@ fn fileSeekTo(userdata: ?*anyopaque, file: File, offset: u64) File.SeekError!voi
74717457
7472 if (posix.SEEK == void) return error.Unseekable;7458 if (posix.SEEK == void) return error.Unseekable;
74737459
7474 return posixSeekTo(current_thread, fd, offset);7460 return posixSeekTo(fd, offset);
7475}7461}
74767462
7477fn posixSeekTo(current_thread: *Thread, fd: posix.fd_t, offset: u64) File.SeekError!void {7463fn posixSeekTo(fd: posix.fd_t, offset: u64) File.SeekError!void {
7478 if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {7464 if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
7479 try current_thread.beginSyscall();7465 const syscall: Syscall = try .start();
7480 while (true) {7466 while (true) {
7481 var result: u64 = undefined;7467 var result: u64 = undefined;
7482 switch (posix.errno(posix.system.llseek(fd, offset, &result, posix.SEEK.SET))) {7468 switch (posix.errno(posix.system.llseek(fd, offset, &result, posix.SEEK.SET))) {
7483 .SUCCESS => {7469 .SUCCESS => {
7484 current_thread.endSyscall();7470 syscall.finish();
7485 return;7471 return;
7486 },7472 },
7487 .INTR => {7473 .INTR => {
7488 try current_thread.checkCancel();7474 try syscall.checkCancel();
7489 continue;7475 continue;
7490 },7476 },
7491 else => |e| {7477 else => |e| {
7492 current_thread.endSyscall();7478 syscall.finish();
7493 switch (e) {7479 switch (e) {
7494 .BADF => |err| return errnoBug(err), // File descriptor used after closed.7480 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
7495 .INVAL => return error.Unseekable,7481 .INVAL => return error.Unseekable,
...@@ -7503,19 +7489,19 @@ fn posixSeekTo(current_thread: *Thread, fd: posix.fd_t, offset: u64) File.SeekEr...@@ -7503,19 +7489,19 @@ fn posixSeekTo(current_thread: *Thread, fd: posix.fd_t, offset: u64) File.SeekEr
7503 }7489 }
7504 }7490 }
75057491
7506 try current_thread.beginSyscall();7492 const syscall: Syscall = try .start();
7507 while (true) {7493 while (true) {
7508 switch (posix.errno(lseek_sym(fd, @bitCast(offset), posix.SEEK.SET))) {7494 switch (posix.errno(lseek_sym(fd, @bitCast(offset), posix.SEEK.SET))) {
7509 .SUCCESS => {7495 .SUCCESS => {
7510 current_thread.endSyscall();7496 syscall.finish();
7511 return;7497 return;
7512 },7498 },
7513 .INTR => {7499 .INTR => {
7514 try current_thread.checkCancel();7500 try syscall.checkCancel();
7515 continue;7501 continue;
7516 },7502 },
7517 else => |e| {7503 else => |e| {
7518 current_thread.endSyscall();7504 syscall.finish();
7519 switch (e) {7505 switch (e) {
7520 .BADF => |err| return errnoBug(err), // File descriptor used after closed.7506 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
7521 .INVAL => return error.Unseekable,7507 .INVAL => return error.Unseekable,
...@@ -7605,22 +7591,21 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex...@@ -7605,22 +7591,21 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
7605 else => |e| return e,7591 else => |e| return e,
7606 },7592 },
7607 .freebsd, .dragonfly => {7593 .freebsd, .dragonfly => {
7608 const current_thread = Thread.getCurrent(t);
7609 var mib: [4]c_int = .{ posix.CTL.KERN, posix.KERN.PROC, posix.KERN.PROC_PATHNAME, -1 };7594 var mib: [4]c_int = .{ posix.CTL.KERN, posix.KERN.PROC, posix.KERN.PROC_PATHNAME, -1 };
7610 var out_len: usize = out_buffer.len;7595 var out_len: usize = out_buffer.len;
7611 try current_thread.beginSyscall();7596 const syscall: Syscall = try .start();
7612 while (true) {7597 while (true) {
7613 switch (posix.errno(posix.system.sysctl(&mib, mib.len, out_buffer.ptr, &out_len, null, 0))) {7598 switch (posix.errno(posix.system.sysctl(&mib, mib.len, out_buffer.ptr, &out_len, null, 0))) {
7614 .SUCCESS => {7599 .SUCCESS => {
7615 current_thread.endSyscall();7600 syscall.finish();
7616 return out_len - 1; // discard terminating NUL7601 return out_len - 1; // discard terminating NUL
7617 },7602 },
7618 .INTR => {7603 .INTR => {
7619 try current_thread.checkCancel();7604 try syscall.checkCancel();
7620 continue;7605 continue;
7621 },7606 },
7622 else => |e| {7607 else => |e| {
7623 current_thread.endSyscall();7608 syscall.finish();
7624 switch (e) {7609 switch (e) {
7625 .FAULT => |err| return errnoBug(err),7610 .FAULT => |err| return errnoBug(err),
7626 .PERM => return error.PermissionDenied,7611 .PERM => return error.PermissionDenied,
...@@ -7633,22 +7618,21 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex...@@ -7633,22 +7618,21 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
7633 }7618 }
7634 },7619 },
7635 .netbsd => {7620 .netbsd => {
7636 const current_thread = Thread.getCurrent(t);
7637 var mib = [4]c_int{ posix.CTL.KERN, posix.KERN.PROC_ARGS, -1, posix.KERN.PROC_PATHNAME };7621 var mib = [4]c_int{ posix.CTL.KERN, posix.KERN.PROC_ARGS, -1, posix.KERN.PROC_PATHNAME };
7638 var out_len: usize = out_buffer.len;7622 var out_len: usize = out_buffer.len;
7639 try current_thread.beginSyscall();7623 const syscall: Syscall = try .start();
7640 while (true) {7624 while (true) {
7641 switch (posix.errno(posix.system.sysctl(&mib, mib.len, out_buffer.ptr, &out_len, null, 0))) {7625 switch (posix.errno(posix.system.sysctl(&mib, mib.len, out_buffer.ptr, &out_len, null, 0))) {
7642 .SUCCESS => {7626 .SUCCESS => {
7643 current_thread.endSyscall();7627 syscall.finish();
7644 return out_len - 1; // discard terminating NUL7628 return out_len - 1; // discard terminating NUL
7645 },7629 },
7646 .INTR => {7630 .INTR => {
7647 try current_thread.checkCancel();7631 try syscall.checkCancel();
7648 continue;7632 continue;
7649 },7633 },
7650 else => |e| {7634 else => |e| {
7651 current_thread.endSyscall();7635 syscall.finish();
7652 switch (e) {7636 switch (e) {
7653 .FAULT => |err| return errnoBug(err),7637 .FAULT => |err| return errnoBug(err),
7654 .PERM => return error.PermissionDenied,7638 .PERM => return error.PermissionDenied,
...@@ -7666,20 +7650,19 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex...@@ -7666,20 +7650,19 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
7666 const argv0 = std.mem.span(t.argv0.value orelse return error.OperationUnsupported);7650 const argv0 = std.mem.span(t.argv0.value orelse return error.OperationUnsupported);
7667 if (std.mem.findScalar(u8, argv0, '/') != null) {7651 if (std.mem.findScalar(u8, argv0, '/') != null) {
7668 // argv[0] is a path (relative or absolute): use realpath(3) directly7652 // argv[0] is a path (relative or absolute): use realpath(3) directly
7669 const current_thread = Thread.getCurrent(t);
7670 var resolved_buf: [std.c.PATH_MAX]u8 = undefined;7653 var resolved_buf: [std.c.PATH_MAX]u8 = undefined;
7671 try current_thread.beginSyscall();7654 const syscall: Syscall = try .start();
7672 while (true) {7655 while (true) {
7673 if (std.c.realpath(argv0, &resolved_buf)) |p| {7656 if (std.c.realpath(argv0, &resolved_buf)) |p| {
7674 assert(p == &resolved_buf);7657 assert(p == &resolved_buf);
7675 break current_thread.endSyscall();7658 break syscall.finish();
7676 } else switch (@as(std.c.E, @enumFromInt(std.c._errno().*))) {7659 } else switch (@as(std.c.E, @enumFromInt(std.c._errno().*))) {
7677 .INTR => {7660 .INTR => {
7678 try current_thread.checkCancel();7661 try syscall.checkCancel();
7679 continue;7662 continue;
7680 },7663 },
7681 else => |e| {7664 else => |e| {
7682 current_thread.endSyscall();7665 syscall.finish();
7683 switch (e) {7666 switch (e) {
7684 .ACCES => return error.AccessDenied,7667 .ACCES => return error.AccessDenied,
7685 .INVAL => |err| return errnoBug(err), // the pathname argument is a null pointer7668 .INVAL => |err| return errnoBug(err), // the pathname argument is a null pointer
...@@ -7703,7 +7686,6 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex...@@ -7703,7 +7686,6 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
7703 // argv[0] is not empty (and not a path): search PATH7686 // argv[0] is not empty (and not a path): search PATH
7704 t.scanEnviron();7687 t.scanEnviron();
7705 const PATH = t.environ.string.PATH orelse return error.FileNotFound;7688 const PATH = t.environ.string.PATH orelse return error.FileNotFound;
7706 const current_thread = Thread.getCurrent(t);
7707 var it = std.mem.tokenizeScalar(u8, PATH, ':');7689 var it = std.mem.tokenizeScalar(u8, PATH, ':');
7708 it: while (it.next()) |dir| {7690 it: while (it.next()) |dir| {
7709 var resolved_path_buf: [std.c.PATH_MAX]u8 = undefined;7691 var resolved_path_buf: [std.c.PATH_MAX]u8 = undefined;
...@@ -7712,34 +7694,34 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex...@@ -7712,34 +7694,34 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
7712 }, 0) catch continue;7694 }, 0) catch continue;
77137695
7714 var resolved_buf: [std.c.PATH_MAX]u8 = undefined;7696 var resolved_buf: [std.c.PATH_MAX]u8 = undefined;
7715 try current_thread.beginSyscall();7697 const syscall: Syscall = try .start();
7716 while (true) {7698 while (true) {
7717 if (std.c.realpath(resolved_path, &resolved_buf)) |p| {7699 if (std.c.realpath(resolved_path, &resolved_buf)) |p| {
7718 assert(p == &resolved_buf);7700 assert(p == &resolved_buf);
7719 break current_thread.endSyscall();7701 break syscall.finish();
7720 } else switch (@as(std.c.E, @enumFromInt(std.c._errno().*))) {7702 } else switch (@as(std.c.E, @enumFromInt(std.c._errno().*))) {
7721 .INTR => {7703 .INTR => {
7722 try current_thread.checkCancel();7704 try syscall.checkCancel();
7723 continue;7705 continue;
7724 },7706 },
7725 .NAMETOOLONG => {7707 .NAMETOOLONG => {
7726 current_thread.endSyscall();7708 syscall.finish();
7727 return error.NameTooLong;7709 return error.NameTooLong;
7728 },7710 },
7729 .NOMEM => {7711 .NOMEM => {
7730 current_thread.endSyscall();7712 syscall.finish();
7731 return error.SystemResources;7713 return error.SystemResources;
7732 },7714 },
7733 .IO => {7715 .IO => {
7734 current_thread.endSyscall();7716 syscall.finish();
7735 return error.InputOutput;7717 return error.InputOutput;
7736 },7718 },
7737 .ACCES, .LOOP, .NOENT, .NOTDIR => {7719 .ACCES, .LOOP, .NOENT, .NOTDIR => {
7738 current_thread.endSyscall();7720 syscall.finish();
7739 continue :it;7721 continue :it;
7740 },7722 },
7741 else => |err| {7723 else => |err| {
7742 current_thread.endSyscall();7724 syscall.finish();
7743 return posix.unexpectedErrno(err);7725 return posix.unexpectedErrno(err);
7744 },7726 },
7745 }7727 }
...@@ -7754,8 +7736,7 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex...@@ -7754,8 +7736,7 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
7754 return error.FileNotFound;7736 return error.FileNotFound;
7755 },7737 },
7756 .windows => {7738 .windows => {
7757 const current_thread = Thread.getCurrent(t);7739 try Thread.checkCancel();
7758 try current_thread.checkCancel();
7759 const w = windows;7740 const w = windows;
7760 const image_path_unicode_string = &w.peb().ProcessParameters.ImagePathName;7741 const image_path_unicode_string = &w.peb().ProcessParameters.ImagePathName;
7761 const image_path_name = image_path_unicode_string.Buffer.?[0 .. image_path_unicode_string.Length / 2 :0];7742 const image_path_name = image_path_unicode_string.Buffer.?[0 .. image_path_unicode_string.Length / 2 :0];
...@@ -7805,19 +7786,19 @@ fn fileWritePositional(...@@ -7805,19 +7786,19 @@ fn fileWritePositional(
7805 offset: u64,7786 offset: u64,
7806) File.WritePositionalError!usize {7787) File.WritePositionalError!usize {
7807 const t: *Threaded = @ptrCast(@alignCast(userdata));7788 const t: *Threaded = @ptrCast(@alignCast(userdata));
7808 const current_thread = Thread.getCurrent(t);7789 _ = t;
78097790
7810 if (is_windows) {7791 if (is_windows) {
7811 if (header.len != 0) {7792 if (header.len != 0) {
7812 return writeFilePositionalWindows(current_thread, file.handle, header, offset);7793 return writeFilePositionalWindows(file.handle, header, offset);
7813 }7794 }
7814 for (data[0 .. data.len - 1]) |buf| {7795 for (data[0 .. data.len - 1]) |buf| {
7815 if (buf.len == 0) continue;7796 if (buf.len == 0) continue;
7816 return writeFilePositionalWindows(current_thread, file.handle, buf, offset);7797 return writeFilePositionalWindows(file.handle, buf, offset);
7817 }7798 }
7818 const pattern = data[data.len - 1];7799 const pattern = data[data.len - 1];
7819 if (pattern.len == 0 or splat == 0) return 0;7800 if (pattern.len == 0 or splat == 0) return 0;
7820 return writeFilePositionalWindows(current_thread, file.handle, pattern, offset);7801 return writeFilePositionalWindows(file.handle, pattern, offset);
7821 }7802 }
78227803
7823 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;7804 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;
...@@ -7855,19 +7836,19 @@ fn fileWritePositional(...@@ -7855,19 +7836,19 @@ fn fileWritePositional(
78557836
7856 if (native_os == .wasi and !builtin.link_libc) {7837 if (native_os == .wasi and !builtin.link_libc) {
7857 var n_written: usize = undefined;7838 var n_written: usize = undefined;
7858 try current_thread.beginSyscall();7839 const syscall: Syscall = try .start();
7859 while (true) {7840 while (true) {
7860 switch (std.os.wasi.fd_pwrite(file.handle, &iovecs, iovlen, offset, &n_written)) {7841 switch (std.os.wasi.fd_pwrite(file.handle, &iovecs, iovlen, offset, &n_written)) {
7861 .SUCCESS => {7842 .SUCCESS => {
7862 current_thread.endSyscall();7843 syscall.finish();
7863 return n_written;7844 return n_written;
7864 },7845 },
7865 .INTR => {7846 .INTR => {
7866 try current_thread.checkCancel();7847 try syscall.checkCancel();
7867 continue;7848 continue;
7868 },7849 },
7869 else => |e| {7850 else => |e| {
7870 current_thread.endSyscall();7851 syscall.finish();
7871 switch (e) {7852 switch (e) {
7872 .INVAL => |err| return errnoBug(err),7853 .INVAL => |err| return errnoBug(err),
7873 .FAULT => |err| return errnoBug(err),7854 .FAULT => |err| return errnoBug(err),
...@@ -7891,20 +7872,20 @@ fn fileWritePositional(...@@ -7891,20 +7872,20 @@ fn fileWritePositional(
7891 }7872 }
7892 }7873 }
78937874
7894 try current_thread.beginSyscall();7875 const syscall: Syscall = try .start();
7895 while (true) {7876 while (true) {
7896 const rc = pwritev_sym(file.handle, &iovecs, @intCast(iovlen), @bitCast(offset));7877 const rc = pwritev_sym(file.handle, &iovecs, @intCast(iovlen), @bitCast(offset));
7897 switch (posix.errno(rc)) {7878 switch (posix.errno(rc)) {
7898 .SUCCESS => {7879 .SUCCESS => {
7899 current_thread.endSyscall();7880 syscall.finish();
7900 return @intCast(rc);7881 return @intCast(rc);
7901 },7882 },
7902 .INTR => {7883 .INTR => {
7903 try current_thread.checkCancel();7884 try syscall.checkCancel();
7904 continue;7885 continue;
7905 },7886 },
7906 else => |e| {7887 else => |e| {
7907 current_thread.endSyscall();7888 syscall.finish();
7908 switch (e) {7889 switch (e) {
7909 .INVAL => |err| return errnoBug(err),7890 .INVAL => |err| return errnoBug(err),
7910 .FAULT => |err| return errnoBug(err),7891 .FAULT => |err| return errnoBug(err),
...@@ -7931,12 +7912,11 @@ fn fileWritePositional(...@@ -7931,12 +7912,11 @@ fn fileWritePositional(
7931}7912}
79327913
7933fn writeFilePositionalWindows(7914fn writeFilePositionalWindows(
7934 current_thread: *Thread,
7935 handle: windows.HANDLE,7915 handle: windows.HANDLE,
7936 bytes: []const u8,7916 bytes: []const u8,
7937 offset: u64,7917 offset: u64,
7938) File.WritePositionalError!usize {7918) File.WritePositionalError!usize {
7939 try current_thread.checkCancel();7919 try Thread.checkCancel();
79407920
7941 var bytes_written: windows.DWORD = undefined;7921 var bytes_written: windows.DWORD = undefined;
7942 var overlapped: windows.OVERLAPPED = .{7922 var overlapped: windows.OVERLAPPED = .{
...@@ -7976,19 +7956,19 @@ fn fileWriteStreaming(...@@ -7976,19 +7956,19 @@ fn fileWriteStreaming(
7976 splat: usize,7956 splat: usize,
7977) File.Writer.Error!usize {7957) File.Writer.Error!usize {
7978 const t: *Threaded = @ptrCast(@alignCast(userdata));7958 const t: *Threaded = @ptrCast(@alignCast(userdata));
7979 const current_thread = Thread.getCurrent(t);7959 _ = t;
79807960
7981 if (is_windows) {7961 if (is_windows) {
7982 if (header.len != 0) {7962 if (header.len != 0) {
7983 return writeFileStreamingWindows(current_thread, file.handle, header);7963 return writeFileStreamingWindows(file.handle, header);
7984 }7964 }
7985 for (data[0 .. data.len - 1]) |buf| {7965 for (data[0 .. data.len - 1]) |buf| {
7986 if (buf.len == 0) continue;7966 if (buf.len == 0) continue;
7987 return writeFileStreamingWindows(current_thread, file.handle, buf);7967 return writeFileStreamingWindows(file.handle, buf);
7988 }7968 }
7989 const pattern = data[data.len - 1];7969 const pattern = data[data.len - 1];
7990 if (pattern.len == 0 or splat == 0) return 0;7970 if (pattern.len == 0 or splat == 0) return 0;
7991 return writeFileStreamingWindows(current_thread, file.handle, pattern);7971 return writeFileStreamingWindows(file.handle, pattern);
7992 }7972 }
79937973
7994 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;7974 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;
...@@ -8026,19 +8006,19 @@ fn fileWriteStreaming(...@@ -8026,19 +8006,19 @@ fn fileWriteStreaming(
80268006
8027 if (native_os == .wasi and !builtin.link_libc) {8007 if (native_os == .wasi and !builtin.link_libc) {
8028 var n_written: usize = undefined;8008 var n_written: usize = undefined;
8029 try current_thread.beginSyscall();8009 const syscall: Syscall = try .start();
8030 while (true) {8010 while (true) {
8031 switch (std.os.wasi.fd_write(file.handle, &iovecs, iovlen, &n_written)) {8011 switch (std.os.wasi.fd_write(file.handle, &iovecs, iovlen, &n_written)) {
8032 .SUCCESS => {8012 .SUCCESS => {
8033 current_thread.endSyscall();8013 syscall.finish();
8034 return n_written;8014 return n_written;
8035 },8015 },
8036 .INTR => {8016 .INTR => {
8037 try current_thread.checkCancel();8017 try syscall.checkCancel();
8038 continue;8018 continue;
8039 },8019 },
8040 else => |e| {8020 else => |e| {
8041 current_thread.endSyscall();8021 syscall.finish();
8042 switch (e) {8022 switch (e) {
8043 .INVAL => |err| return errnoBug(err),8023 .INVAL => |err| return errnoBug(err),
8044 .FAULT => |err| return errnoBug(err),8024 .FAULT => |err| return errnoBug(err),
...@@ -8059,20 +8039,20 @@ fn fileWriteStreaming(...@@ -8059,20 +8039,20 @@ fn fileWriteStreaming(
8059 }8039 }
8060 }8040 }
80618041
8062 try current_thread.beginSyscall();8042 const syscall: Syscall = try .start();
8063 while (true) {8043 while (true) {
8064 const rc = posix.system.writev(file.handle, &iovecs, @intCast(iovlen));8044 const rc = posix.system.writev(file.handle, &iovecs, @intCast(iovlen));
8065 switch (posix.errno(rc)) {8045 switch (posix.errno(rc)) {
8066 .SUCCESS => {8046 .SUCCESS => {
8067 current_thread.endSyscall();8047 syscall.finish();
8068 return @intCast(rc);8048 return @intCast(rc);
8069 },8049 },
8070 .INTR => {8050 .INTR => {
8071 try current_thread.checkCancel();8051 try syscall.checkCancel();
8072 continue;8052 continue;
8073 },8053 },
8074 else => |e| {8054 else => |e| {
8075 current_thread.endSyscall();8055 syscall.finish();
8076 switch (e) {8056 switch (e) {
8077 .INVAL => |err| return errnoBug(err),8057 .INVAL => |err| return errnoBug(err),
8078 .FAULT => |err| return errnoBug(err),8058 .FAULT => |err| return errnoBug(err),
...@@ -8095,11 +8075,10 @@ fn fileWriteStreaming(...@@ -8095,11 +8075,10 @@ fn fileWriteStreaming(
8095}8075}
80968076
8097fn writeFileStreamingWindows(8077fn writeFileStreamingWindows(
8098 current_thread: *Thread,
8099 handle: windows.HANDLE,8078 handle: windows.HANDLE,
8100 bytes: []const u8,8079 bytes: []const u8,
8101) File.Writer.Error!usize {8080) File.Writer.Error!usize {
8102 try current_thread.checkCancel();8081 try Thread.checkCancel();
81038082
8104 var bytes_written: windows.DWORD = undefined;8083 var bytes_written: windows.DWORD = undefined;
8105 const adjusted_len = std.math.lossyCast(u32, bytes.len);8084 const adjusted_len = std.math.lossyCast(u32, bytes.len);
...@@ -8178,40 +8157,39 @@ fn fileWriteFileStreaming(...@@ -8178,40 +8157,39 @@ fn fileWriteFileStreaming(
8178 const nbytes: usize = @min(file_limit, std.math.maxInt(usize));8157 const nbytes: usize = @min(file_limit, std.math.maxInt(usize));
8179 const flags = 0;8158 const flags = 0;
81808159
8181 const current_thread = Thread.getCurrent(t);8160 const syscall: Syscall = try .start();
8182 try current_thread.beginSyscall();
8183 while (true) {8161 while (true) {
8184 switch (posix.errno(std.c.sendfile(in_fd, out_fd, offset, nbytes, hdtr, &sbytes, flags))) {8162 switch (posix.errno(std.c.sendfile(in_fd, out_fd, offset, nbytes, hdtr, &sbytes, flags))) {
8185 .SUCCESS => {8163 .SUCCESS => {
8186 current_thread.endSyscall();8164 syscall.finish();
8187 break;8165 break;
8188 },8166 },
8189 .INVAL, .OPNOTSUPP, .NOTSOCK, .NOSYS => {8167 .INVAL, .OPNOTSUPP, .NOTSOCK, .NOSYS => {
8190 // Give calling code chance to observe before trying8168 // Give calling code chance to observe before trying
8191 // something else.8169 // something else.
8192 current_thread.endSyscall();8170 syscall.finish();
8193 @atomicStore(UseSendfile, &t.use_sendfile, .disabled, .monotonic);8171 @atomicStore(UseSendfile, &t.use_sendfile, .disabled, .monotonic);
8194 return 0;8172 return 0;
8195 },8173 },
8196 .INTR, .BUSY => {8174 .INTR, .BUSY => {
8197 if (sbytes == 0) {8175 if (sbytes == 0) {
8198 try current_thread.checkCancel();8176 try syscall.checkCancel();
8199 continue;8177 continue;
8200 } else {8178 } else {
8201 // Even if we are being canceled, there have been side8179 // Even if we are being canceled, there have been side
8202 // effects, so it is better to report those side8180 // effects, so it is better to report those side
8203 // effects to the caller.8181 // effects to the caller.
8204 current_thread.endSyscall();8182 syscall.finish();
8205 break;8183 break;
8206 }8184 }
8207 },8185 },
8208 .AGAIN => {8186 .AGAIN => {
8209 current_thread.endSyscall();8187 syscall.finish();
8210 if (sbytes == 0) return error.WouldBlock;8188 if (sbytes == 0) return error.WouldBlock;
8211 break;8189 break;
8212 },8190 },
8213 else => |e| {8191 else => |e| {
8214 current_thread.endSyscall();8192 syscall.finish();
8215 assert(error.Unexpected == switch (e) {8193 assert(error.Unexpected == switch (e) {
8216 .NOTCONN => return error.BrokenPipe,8194 .NOTCONN => return error.BrokenPipe,
8217 .IO => return error.InputOutput,8195 .IO => return error.InputOutput,
...@@ -8264,40 +8242,39 @@ fn fileWriteFileStreaming(...@@ -8264,40 +8242,39 @@ fn fileWriteFileStreaming(
8264 const max_count = std.math.maxInt(i32); // Avoid EINVAL.8242 const max_count = std.math.maxInt(i32); // Avoid EINVAL.
8265 var len: std.c.off_t = @min(file_limit, max_count);8243 var len: std.c.off_t = @min(file_limit, max_count);
8266 const flags = 0;8244 const flags = 0;
8267 const current_thread = Thread.getCurrent(t);8245 const syscall: Syscall = try .start();
8268 try current_thread.beginSyscall();
8269 while (true) {8246 while (true) {
8270 switch (posix.errno(std.c.sendfile(in_fd, out_fd, offset, &len, hdtr, flags))) {8247 switch (posix.errno(std.c.sendfile(in_fd, out_fd, offset, &len, hdtr, flags))) {
8271 .SUCCESS => {8248 .SUCCESS => {
8272 current_thread.endSyscall();8249 syscall.finish();
8273 break;8250 break;
8274 },8251 },
8275 .OPNOTSUPP, .NOTSOCK, .NOSYS => {8252 .OPNOTSUPP, .NOTSOCK, .NOSYS => {
8276 // Give calling code chance to observe before trying8253 // Give calling code chance to observe before trying
8277 // something else.8254 // something else.
8278 current_thread.endSyscall();8255 syscall.finish();
8279 @atomicStore(UseSendfile, &t.use_sendfile, .disabled, .monotonic);8256 @atomicStore(UseSendfile, &t.use_sendfile, .disabled, .monotonic);
8280 return 0;8257 return 0;
8281 },8258 },
8282 .INTR => {8259 .INTR => {
8283 if (len == 0) {8260 if (len == 0) {
8284 try current_thread.checkCancel();8261 try syscall.checkCancel();
8285 continue;8262 continue;
8286 } else {8263 } else {
8287 // Even if we are being canceled, there have been side8264 // Even if we are being canceled, there have been side
8288 // effects, so it is better to report those side8265 // effects, so it is better to report those side
8289 // effects to the caller.8266 // effects to the caller.
8290 current_thread.endSyscall();8267 syscall.finish();
8291 break;8268 break;
8292 }8269 }
8293 },8270 },
8294 .AGAIN => {8271 .AGAIN => {
8295 current_thread.endSyscall();8272 syscall.finish();
8296 if (len == 0) return error.WouldBlock;8273 if (len == 0) return error.WouldBlock;
8297 break;8274 break;
8298 },8275 },
8299 else => |e| {8276 else => |e| {
8300 current_thread.endSyscall();8277 syscall.finish();
8301 assert(error.Unexpected == switch (e) {8278 assert(error.Unexpected == switch (e) {
8302 .NOTCONN => return error.BrokenPipe,8279 .NOTCONN => return error.BrokenPipe,
8303 .IO => return error.InputOutput,8280 .IO => return error.InputOutput,
...@@ -8344,28 +8321,27 @@ fn fileWriteFileStreaming(...@@ -8344,28 +8321,27 @@ fn fileWriteFileStreaming(
8344 .streaming_simple, .positional_simple => break :sf,8321 .streaming_simple, .positional_simple => break :sf,
8345 .failure => return error.ReadFailed,8322 .failure => return error.ReadFailed,
8346 };8323 };
8347 const current_thread = Thread.getCurrent(t);8324 const syscall: Syscall = try .start();
8348 try current_thread.beginSyscall();
8349 const n: usize = while (true) {8325 const n: usize = while (true) {
8350 const rc = sendfile_sym(out_fd, in_fd, off_ptr, count);8326 const rc = sendfile_sym(out_fd, in_fd, off_ptr, count);
8351 switch (posix.errno(rc)) {8327 switch (posix.errno(rc)) {
8352 .SUCCESS => {8328 .SUCCESS => {
8353 current_thread.endSyscall();8329 syscall.finish();
8354 break @intCast(rc);8330 break @intCast(rc);
8355 },8331 },
8356 .NOSYS, .INVAL => {8332 .NOSYS, .INVAL => {
8357 // Give calling code chance to observe before trying8333 // Give calling code chance to observe before trying
8358 // something else.8334 // something else.
8359 current_thread.endSyscall();8335 syscall.finish();
8360 @atomicStore(UseSendfile, &t.use_sendfile, .disabled, .monotonic);8336 @atomicStore(UseSendfile, &t.use_sendfile, .disabled, .monotonic);
8361 return 0;8337 return 0;
8362 },8338 },
8363 .INTR => {8339 .INTR => {
8364 try current_thread.checkCancel();8340 try syscall.checkCancel();
8365 continue;8341 continue;
8366 },8342 },
8367 else => |e| {8343 else => |e| {
8368 current_thread.endSyscall();8344 syscall.finish();
8369 assert(error.Unexpected == switch (e) {8345 assert(error.Unexpected == switch (e) {
8370 .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket8346 .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket
8371 .AGAIN => return error.WouldBlock,8347 .AGAIN => return error.WouldBlock,
...@@ -8421,30 +8397,29 @@ fn fileWriteFileStreaming(...@@ -8421,30 +8397,29 @@ fn fileWriteFileStreaming(
8421 .streaming => null,8397 .streaming => null,
8422 .failure => return error.ReadFailed,8398 .failure => return error.ReadFailed,
8423 };8399 };
8424 const current_thread = Thread.getCurrent(t);
8425 const n: usize = switch (native_os) {8400 const n: usize = switch (native_os) {
8426 .linux => n: {8401 .linux => n: {
8427 try current_thread.beginSyscall();8402 const syscall: Syscall = try .start();
8428 while (true) {8403 while (true) {
8429 const rc = linux_copy_file_range_sys.copy_file_range(in_fd, off_in_ptr, out_fd, null, @intFromEnum(limit), 0);8404 const rc = linux_copy_file_range_sys.copy_file_range(in_fd, off_in_ptr, out_fd, null, @intFromEnum(limit), 0);
8430 switch (linux_copy_file_range_sys.errno(rc)) {8405 switch (linux_copy_file_range_sys.errno(rc)) {
8431 .SUCCESS => {8406 .SUCCESS => {
8432 current_thread.endSyscall();8407 syscall.finish();
8433 break :n @intCast(rc);8408 break :n @intCast(rc);
8434 },8409 },
8435 .INTR => {8410 .INTR => {
8436 try current_thread.checkCancel();8411 try syscall.checkCancel();
8437 continue;8412 continue;
8438 },8413 },
8439 .OPNOTSUPP, .INVAL, .NOSYS => {8414 .OPNOTSUPP, .INVAL, .NOSYS => {
8440 // Give calling code chance to observe before trying8415 // Give calling code chance to observe before trying
8441 // something else.8416 // something else.
8442 current_thread.endSyscall();8417 syscall.finish();
8443 @atomicStore(UseCopyFileRange, &t.use_copy_file_range, .disabled, .monotonic);8418 @atomicStore(UseCopyFileRange, &t.use_copy_file_range, .disabled, .monotonic);
8444 return 0;8419 return 0;
8445 },8420 },
8446 else => |e| {8421 else => |e| {
8447 current_thread.endSyscall();8422 syscall.finish();
8448 assert(error.Unexpected == switch (e) {8423 assert(error.Unexpected == switch (e) {
8449 .FBIG => return error.FileTooBig,8424 .FBIG => return error.FileTooBig,
8450 .IO => return error.InputOutput,8425 .IO => return error.InputOutput,
...@@ -8468,27 +8443,27 @@ fn fileWriteFileStreaming(...@@ -8468,27 +8443,27 @@ fn fileWriteFileStreaming(
8468 }8443 }
8469 },8444 },
8470 .freebsd => n: {8445 .freebsd => n: {
8471 try current_thread.beginSyscall();8446 const syscall: Syscall = try .start();
8472 while (true) {8447 while (true) {
8473 const rc = std.c.copy_file_range(in_fd, off_in_ptr, out_fd, null, @intFromEnum(limit), 0);8448 const rc = std.c.copy_file_range(in_fd, off_in_ptr, out_fd, null, @intFromEnum(limit), 0);
8474 switch (std.c.errno(rc)) {8449 switch (std.c.errno(rc)) {
8475 .SUCCESS => {8450 .SUCCESS => {
8476 current_thread.endSyscall();8451 syscall.finish();
8477 break :n @intCast(rc);8452 break :n @intCast(rc);
8478 },8453 },
8479 .INTR => {8454 .INTR => {
8480 try current_thread.checkCancel();8455 try syscall.checkCancel();
8481 continue;8456 continue;
8482 },8457 },
8483 .OPNOTSUPP, .INVAL, .NOSYS => {8458 .OPNOTSUPP, .INVAL, .NOSYS => {
8484 // Give calling code chance to observe before trying8459 // Give calling code chance to observe before trying
8485 // something else.8460 // something else.
8486 current_thread.endSyscall();8461 syscall.finish();
8487 @atomicStore(UseCopyFileRange, &t.use_copy_file_range, .disabled, .monotonic);8462 @atomicStore(UseCopyFileRange, &t.use_copy_file_range, .disabled, .monotonic);
8488 return 0;8463 return 0;
8489 },8464 },
8490 else => |e| {8465 else => |e| {
8491 current_thread.endSyscall();8466 syscall.finish();
8492 assert(error.Unexpected == switch (e) {8467 assert(error.Unexpected == switch (e) {
8493 .FBIG => return error.FileTooBig,8468 .FBIG => return error.FileTooBig,
8494 .IO => return error.InputOutput,8469 .IO => return error.InputOutput,
...@@ -8597,30 +8572,29 @@ fn fileWriteFilePositional(...@@ -8597,30 +8572,29 @@ fn fileWriteFilePositional(
8597 .failure => return error.ReadFailed,8572 .failure => return error.ReadFailed,
8598 };8573 };
8599 var off_out: i64 = @intCast(offset);8574 var off_out: i64 = @intCast(offset);
8600 const current_thread = Thread.getCurrent(t);
8601 const n: usize = switch (native_os) {8575 const n: usize = switch (native_os) {
8602 .linux => n: {8576 .linux => n: {
8603 try current_thread.beginSyscall();8577 const syscall: Syscall = try .start();
8604 while (true) {8578 while (true) {
8605 const rc = linux_copy_file_range_sys.copy_file_range(in_fd, off_in_ptr, out_fd, &off_out, @intFromEnum(limit), 0);8579 const rc = linux_copy_file_range_sys.copy_file_range(in_fd, off_in_ptr, out_fd, &off_out, @intFromEnum(limit), 0);
8606 switch (linux_copy_file_range_sys.errno(rc)) {8580 switch (linux_copy_file_range_sys.errno(rc)) {
8607 .SUCCESS => {8581 .SUCCESS => {
8608 current_thread.endSyscall();8582 syscall.finish();
8609 break :n @intCast(rc);8583 break :n @intCast(rc);
8610 },8584 },
8611 .INTR => {8585 .INTR => {
8612 try current_thread.checkCancel();8586 try syscall.checkCancel();
8613 continue;8587 continue;
8614 },8588 },
8615 .OPNOTSUPP, .INVAL, .NOSYS => {8589 .OPNOTSUPP, .INVAL, .NOSYS => {
8616 // Give calling code chance to observe before trying8590 // Give calling code chance to observe before trying
8617 // something else.8591 // something else.
8618 current_thread.endSyscall();8592 syscall.finish();
8619 @atomicStore(UseCopyFileRange, &t.use_copy_file_range, .disabled, .monotonic);8593 @atomicStore(UseCopyFileRange, &t.use_copy_file_range, .disabled, .monotonic);
8620 return 0;8594 return 0;
8621 },8595 },
8622 else => |e| {8596 else => |e| {
8623 current_thread.endSyscall();8597 syscall.finish();
8624 assert(error.Unexpected == switch (e) {8598 assert(error.Unexpected == switch (e) {
8625 .FBIG => return error.FileTooBig,8599 .FBIG => return error.FileTooBig,
8626 .IO => return error.InputOutput,8600 .IO => return error.InputOutput,
...@@ -8645,27 +8619,27 @@ fn fileWriteFilePositional(...@@ -8645,27 +8619,27 @@ fn fileWriteFilePositional(
8645 }8619 }
8646 },8620 },
8647 .freebsd => n: {8621 .freebsd => n: {
8648 try current_thread.beginSyscall();8622 const syscall: Syscall = try .start();
8649 while (true) {8623 while (true) {
8650 const rc = std.c.copy_file_range(in_fd, off_in_ptr, out_fd, &off_out, @intFromEnum(limit), 0);8624 const rc = std.c.copy_file_range(in_fd, off_in_ptr, out_fd, &off_out, @intFromEnum(limit), 0);
8651 switch (std.c.errno(rc)) {8625 switch (std.c.errno(rc)) {
8652 .SUCCESS => {8626 .SUCCESS => {
8653 current_thread.endSyscall();8627 syscall.finish();
8654 break :n @intCast(rc);8628 break :n @intCast(rc);
8655 },8629 },
8656 .INTR => {8630 .INTR => {
8657 try current_thread.checkCancel();8631 try syscall.checkCancel();
8658 continue;8632 continue;
8659 },8633 },
8660 .OPNOTSUPP, .INVAL, .NOSYS => {8634 .OPNOTSUPP, .INVAL, .NOSYS => {
8661 // Give calling code chance to observe before trying8635 // Give calling code chance to observe before trying
8662 // something else.8636 // something else.
8663 current_thread.endSyscall();8637 syscall.finish();
8664 @atomicStore(UseCopyFileRange, &t.use_copy_file_range, .disabled, .monotonic);8638 @atomicStore(UseCopyFileRange, &t.use_copy_file_range, .disabled, .monotonic);
8665 return 0;8639 return 0;
8666 },8640 },
8667 else => |e| {8641 else => |e| {
8668 current_thread.endSyscall();8642 syscall.finish();
8669 assert(error.Unexpected == switch (e) {8643 assert(error.Unexpected == switch (e) {
8670 .FBIG => return error.FileTooBig,8644 .FBIG => return error.FileTooBig,
8671 .IO => return error.InputOutput,8645 .IO => return error.InputOutput,
...@@ -8705,28 +8679,27 @@ fn fileWriteFilePositional(...@@ -8705,28 +8679,27 @@ fn fileWriteFilePositional(
8705 file_reader.interface.toss(n -| header.len);8679 file_reader.interface.toss(n -| header.len);
8706 return n;8680 return n;
8707 }8681 }
8708 const current_thread = Thread.getCurrent(t);8682 const syscall: Syscall = try .start();
8709 try current_thread.beginSyscall();
8710 while (true) {8683 while (true) {
8711 const rc = std.c.fcopyfile(in_fd, out_fd, null, .{ .DATA = true });8684 const rc = std.c.fcopyfile(in_fd, out_fd, null, .{ .DATA = true });
8712 switch (posix.errno(rc)) {8685 switch (posix.errno(rc)) {
8713 .SUCCESS => {8686 .SUCCESS => {
8714 current_thread.endSyscall();8687 syscall.finish();
8715 break;8688 break;
8716 },8689 },
8717 .INTR => {8690 .INTR => {
8718 try current_thread.checkCancel();8691 try syscall.checkCancel();
8719 continue;8692 continue;
8720 },8693 },
8721 .OPNOTSUPP => {8694 .OPNOTSUPP => {
8722 // Give calling code chance to observe before trying8695 // Give calling code chance to observe before trying
8723 // something else.8696 // something else.
8724 current_thread.endSyscall();8697 syscall.finish();
8725 @atomicStore(UseFcopyfile, &t.use_fcopyfile, .disabled, .monotonic);8698 @atomicStore(UseFcopyfile, &t.use_fcopyfile, .disabled, .monotonic);
8726 return 0;8699 return 0;
8727 },8700 },
8728 else => |e| {8701 else => |e| {
8729 current_thread.endSyscall();8702 syscall.finish();
8730 assert(error.Unexpected == switch (e) {8703 assert(error.Unexpected == switch (e) {
8731 .NOMEM => return error.SystemResources,8704 .NOMEM => return error.SystemResources,
8732 .INVAL => |err| errnoBug(err),8705 .INVAL => |err| errnoBug(err),
...@@ -8814,7 +8787,7 @@ const sleep = switch (native_os) {...@@ -8814,7 +8787,7 @@ const sleep = switch (native_os) {
88148787
8815fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {8788fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
8816 const t: *Threaded = @ptrCast(@alignCast(userdata));8789 const t: *Threaded = @ptrCast(@alignCast(userdata));
8817 const current_thread = Thread.getCurrent(t);8790 _ = t;
8818 const clock_id: posix.clockid_t = clockToPosix(switch (timeout) {8791 const clock_id: posix.clockid_t = clockToPosix(switch (timeout) {
8819 .none => .awake,8792 .none => .awake,
8820 .duration => |d| d.clock,8793 .duration => |d| d.clock,
...@@ -8826,22 +8799,22 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -8826,22 +8799,22 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
8826 .deadline => |deadline| deadline.raw.nanoseconds,8799 .deadline => |deadline| deadline.raw.nanoseconds,
8827 };8800 };
8828 var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);8801 var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);
8829 try current_thread.beginSyscall();8802 const syscall: Syscall = try .start();
8830 while (true) {8803 while (true) {
8831 switch (std.os.linux.errno(std.os.linux.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {8804 switch (std.os.linux.errno(std.os.linux.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {
8832 .none, .duration => false,8805 .none, .duration => false,
8833 .deadline => true,8806 .deadline => true,
8834 } }, &timespec, &timespec))) {8807 } }, &timespec, &timespec))) {
8835 .SUCCESS => {8808 .SUCCESS => {
8836 current_thread.endSyscall();8809 syscall.finish();
8837 return;8810 return;
8838 },8811 },
8839 .INTR => {8812 .INTR => {
8840 try current_thread.checkCancel();8813 try syscall.checkCancel();
8841 continue;8814 continue;
8842 },8815 },
8843 else => |e| {8816 else => |e| {
8844 current_thread.endSyscall();8817 syscall.finish();
8845 switch (e) {8818 switch (e) {
8846 .INVAL => return error.UnsupportedClock,8819 .INVAL => return error.UnsupportedClock,
8847 else => |err| return posix.unexpectedErrno(err),8820 else => |err| return posix.unexpectedErrno(err),
...@@ -8853,9 +8826,8 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -8853,9 +8826,8 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
88538826
8854fn sleepWindows(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {8827fn sleepWindows(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
8855 const t: *Threaded = @ptrCast(@alignCast(userdata));8828 const t: *Threaded = @ptrCast(@alignCast(userdata));
8856 const current_thread = Thread.getCurrent(t);
8857 const t_io = ioBasic(t);8829 const t_io = ioBasic(t);
8858 try current_thread.checkCancel();8830 try Thread.checkCancel();
8859 const ms = ms: {8831 const ms = ms: {
8860 const d = (try timeout.toDurationFromNow(t_io)) orelse8832 const d = (try timeout.toDurationFromNow(t_io)) orelse
8861 break :ms std.math.maxInt(windows.DWORD);8833 break :ms std.math.maxInt(windows.DWORD);
...@@ -8867,7 +8839,6 @@ fn sleepWindows(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -8867,7 +8839,6 @@ fn sleepWindows(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
88678839
8868fn sleepWasi(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {8840fn sleepWasi(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
8869 const t: *Threaded = @ptrCast(@alignCast(userdata));8841 const t: *Threaded = @ptrCast(@alignCast(userdata));
8870 const current_thread = Thread.getCurrent(t);
8871 const t_io = ioBasic(t);8842 const t_io = ioBasic(t);
8872 const w = std.os.wasi;8843 const w = std.os.wasi;
88738844
...@@ -8891,14 +8862,13 @@ fn sleepWasi(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -8891,14 +8862,13 @@ fn sleepWasi(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
8891 };8862 };
8892 var event: w.event_t = undefined;8863 var event: w.event_t = undefined;
8893 var nevents: usize = undefined;8864 var nevents: usize = undefined;
8894 try current_thread.beginSyscall();8865 const syscall: Syscall = try .start();
8895 _ = w.poll_oneoff(&in, &event, 1, &nevents);8866 _ = w.poll_oneoff(&in, &event, 1, &nevents);
8896 current_thread.endSyscall();8867 syscall.finish();
8897}8868}
88988869
8899fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {8870fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
8900 const t: *Threaded = @ptrCast(@alignCast(userdata));8871 const t: *Threaded = @ptrCast(@alignCast(userdata));
8901 const current_thread = Thread.getCurrent(t);
8902 const t_io = ioBasic(t);8872 const t_io = ioBasic(t);
8903 const sec_type = @typeInfo(posix.timespec).@"struct".fields[0].type;8873 const sec_type = @typeInfo(posix.timespec).@"struct".fields[0].type;
8904 const nsec_type = @typeInfo(posix.timespec).@"struct".fields[1].type;8874 const nsec_type = @typeInfo(posix.timespec).@"struct".fields[1].type;
...@@ -8910,21 +8880,22 @@ fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {...@@ -8910,21 +8880,22 @@ fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
8910 };8880 };
8911 break :t timestampToPosix(d.raw.toNanoseconds());8881 break :t timestampToPosix(d.raw.toNanoseconds());
8912 };8882 };
8913 try current_thread.beginSyscall();8883 const syscall: Syscall = try .start();
8914 while (true) {8884 while (true) {
8915 switch (posix.errno(posix.system.nanosleep(&timespec, &timespec))) {8885 switch (posix.errno(posix.system.nanosleep(&timespec, &timespec))) {
8916 .INTR => {8886 .INTR => {
8917 try current_thread.checkCancel();8887 try syscall.checkCancel();
8918 continue;8888 continue;
8919 },8889 },
8920 // This prong handles success as well as unexpected errors.8890 // This prong handles success as well as unexpected errors.
8921 else => return current_thread.endSyscall(),8891 else => return syscall.finish(),
8922 }8892 }
8923 }8893 }
8924}8894}
89258895
8926fn select(userdata: ?*anyopaque, futures: []const *Io.AnyFuture) Io.Cancelable!usize {8896fn select(userdata: ?*anyopaque, futures: []const *Io.AnyFuture) Io.Cancelable!usize {
8927 const t: *Threaded = @ptrCast(@alignCast(userdata));8897 const t: *Threaded = @ptrCast(@alignCast(userdata));
8898 _ = t;
89288899
8929 var num_completed: std.atomic.Value(u32) = .init(0);8900 var num_completed: std.atomic.Value(u32) = .init(0);
89308901
...@@ -8948,13 +8919,12 @@ fn select(userdata: ?*anyopaque, futures: []const *Io.AnyFuture) Io.Cancelable!u...@@ -8948,13 +8919,12 @@ fn select(userdata: ?*anyopaque, futures: []const *Io.AnyFuture) Io.Cancelable!u
8948 }8919 }
89498920
8950 errdefer _ = finishSelect(&num_completed, futures);8921 errdefer _ = finishSelect(&num_completed, futures);
8951 const thread: *Thread = .getCurrent(t);
89528922
8953 while (true) {8923 while (true) {
8954 const n = num_completed.load(.acquire);8924 const n = num_completed.load(.acquire);
8955 if (n > 0) break;8925 if (n > 0) break;
8956 assert(n < futures.len);8926 assert(n < futures.len);
8957 try thread.futexWait(&num_completed.raw, n);8927 try Thread.futexWait(&num_completed.raw, n, null);
8958 }8928 }
8959 return finishSelect(&num_completed, futures).?;8929 return finishSelect(&num_completed, futures).?;
8960}8930}
...@@ -8986,7 +8956,7 @@ fn finishSelect(...@@ -8986,7 +8956,7 @@ fn finishSelect(
8986 const n = num_completed.load(.acquire);8956 const n = num_completed.load(.acquire);
8987 if (n == expect_completed) break;8957 if (n == expect_completed) break;
8988 assert(n < expect_completed);8958 assert(n < expect_completed);
8989 Thread.futexWaitUncancelable(&num_completed.raw, n);8959 Thread.futexWaitUncancelable(&num_completed.raw, n, null);
8990 }8960 }
8991 return completed_index;8961 return completed_index;
8992}8962}
...@@ -8998,37 +8968,37 @@ fn netListenIpPosix(...@@ -8998,37 +8968,37 @@ fn netListenIpPosix(
8998) IpAddress.ListenError!net.Server {8968) IpAddress.ListenError!net.Server {
8999 if (!have_networking) return error.NetworkDown;8969 if (!have_networking) return error.NetworkDown;
9000 const t: *Threaded = @ptrCast(@alignCast(userdata));8970 const t: *Threaded = @ptrCast(@alignCast(userdata));
9001 const current_thread = Thread.getCurrent(t);8971 _ = t;
9002 const family = posixAddressFamily(&address);8972 const family = posixAddressFamily(&address);
9003 const socket_fd = try openSocketPosix(current_thread, family, .{8973 const socket_fd = try openSocketPosix(family, .{
9004 .mode = options.mode,8974 .mode = options.mode,
9005 .protocol = options.protocol,8975 .protocol = options.protocol,
9006 });8976 });
9007 errdefer posix.close(socket_fd);8977 errdefer posix.close(socket_fd);
90088978
9009 if (options.reuse_address) {8979 if (options.reuse_address) {
9010 try setSocketOption(current_thread, socket_fd, posix.SOL.SOCKET, posix.SO.REUSEADDR, 1);8980 try setSocketOption(socket_fd, posix.SOL.SOCKET, posix.SO.REUSEADDR, 1);
9011 if (@hasDecl(posix.SO, "REUSEPORT"))8981 if (@hasDecl(posix.SO, "REUSEPORT"))
9012 try setSocketOption(current_thread, socket_fd, posix.SOL.SOCKET, posix.SO.REUSEPORT, 1);8982 try setSocketOption(socket_fd, posix.SOL.SOCKET, posix.SO.REUSEPORT, 1);
9013 }8983 }
90148984
9015 var storage: PosixAddress = undefined;8985 var storage: PosixAddress = undefined;
9016 var addr_len = addressToPosix(&address, &storage);8986 var addr_len = addressToPosix(&address, &storage);
9017 try posixBind(current_thread, socket_fd, &storage.any, addr_len);8987 try posixBind(socket_fd, &storage.any, addr_len);
90188988
9019 try current_thread.beginSyscall();8989 const syscall: Syscall = try .start();
9020 while (true) {8990 while (true) {
9021 switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {8991 switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {
9022 .SUCCESS => {8992 .SUCCESS => {
9023 current_thread.endSyscall();8993 syscall.finish();
9024 break;8994 break;
9025 },8995 },
9026 .INTR => {8996 .INTR => {
9027 try current_thread.checkCancel();8997 try syscall.checkCancel();
9028 continue;8998 continue;
9029 },8999 },
9030 else => |e| {9000 else => |e| {
9031 current_thread.endSyscall();9001 syscall.finish();
9032 switch (e) {9002 switch (e) {
9033 .ADDRINUSE => return error.AddressInUse,9003 .ADDRINUSE => return error.AddressInUse,
9034 .BADF => |err| return errnoBug(err), // File descriptor used after closed.9004 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -9038,7 +9008,7 @@ fn netListenIpPosix(...@@ -9038,7 +9008,7 @@ fn netListenIpPosix(
9038 }9008 }
9039 }9009 }
90409010
9041 try posixGetSockName(current_thread, socket_fd, &storage.any, &addr_len);9011 try posixGetSockName(socket_fd, &storage.any, &addr_len);
9042 return .{9012 return .{
9043 .socket = .{9013 .socket = .{
9044 .handle = socket_fd,9014 .handle = socket_fd,
...@@ -9054,9 +9024,8 @@ fn netListenIpWindows(...@@ -9054,9 +9024,8 @@ fn netListenIpWindows(
9054) IpAddress.ListenError!net.Server {9024) IpAddress.ListenError!net.Server {
9055 if (!have_networking) return error.NetworkDown;9025 if (!have_networking) return error.NetworkDown;
9056 const t: *Threaded = @ptrCast(@alignCast(userdata));9026 const t: *Threaded = @ptrCast(@alignCast(userdata));
9057 const current_thread = Thread.getCurrent(t);
9058 const family = posixAddressFamily(&address);9027 const family = posixAddressFamily(&address);
9059 const socket_handle = try openSocketWsa(t, current_thread, family, .{9028 const socket_handle = try openSocketWsa(t, family, .{
9060 .mode = options.mode,9029 .mode = options.mode,
9061 .protocol = options.protocol,9030 .protocol = options.protocol,
9062 });9031 });
...@@ -9068,76 +9037,79 @@ fn netListenIpWindows(...@@ -9068,76 +9037,79 @@ fn netListenIpWindows(
9068 var storage: WsaAddress = undefined;9037 var storage: WsaAddress = undefined;
9069 var addr_len = addressToWsa(&address, &storage);9038 var addr_len = addressToWsa(&address, &storage);
90709039
9071 try current_thread.beginSyscall();9040 {
9072 while (true) {9041 const syscall: Syscall = try .start();
9073 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);9042 while (true) {
9074 if (rc != ws2_32.SOCKET_ERROR) {9043 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
9075 current_thread.endSyscall();9044 if (rc != ws2_32.SOCKET_ERROR) {
9076 break;9045 syscall.finish();
9077 }9046 break;
9078 switch (ws2_32.WSAGetLastError()) {9047 }
9079 .EINTR => {9048 switch (ws2_32.WSAGetLastError()) {
9080 try current_thread.checkCancel();9049 .EINTR => {
9081 continue;9050 try syscall.checkCancel();
9082 },9051 continue;
9083 .NOTINITIALISED => {9052 },
9084 try initializeWsa(t);9053 .NOTINITIALISED => {
9085 try current_thread.checkCancel();9054 try initializeWsa(t);
9086 continue;9055 try syscall.checkCancel();
9087 },9056 continue;
9088 else => |e| {9057 },
9089 current_thread.endSyscall();9058 else => |e| {
9090 switch (e) {9059 syscall.finish();
9091 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,9060 switch (e) {
9092 .EADDRINUSE => return error.AddressInUse,9061 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
9093 .EADDRNOTAVAIL => return error.AddressUnavailable,9062 .EADDRINUSE => return error.AddressInUse,
9094 .ENOTSOCK => |err| return wsaErrorBug(err),9063 .EADDRNOTAVAIL => return error.AddressUnavailable,
9095 .EFAULT => |err| return wsaErrorBug(err),9064 .ENOTSOCK => |err| return wsaErrorBug(err),
9096 .EINVAL => |err| return wsaErrorBug(err),9065 .EFAULT => |err| return wsaErrorBug(err),
9097 .ENOBUFS => return error.SystemResources,9066 .EINVAL => |err| return wsaErrorBug(err),
9098 .ENETDOWN => return error.NetworkDown,9067 .ENOBUFS => return error.SystemResources,
9099 else => |err| return windows.unexpectedWSAError(err),9068 .ENETDOWN => return error.NetworkDown,
9100 }9069 else => |err| return windows.unexpectedWSAError(err),
9101 },9070 }
9071 },
9072 }
9102 }9073 }
9103 }9074 }
91049075 {
9105 try current_thread.beginSyscall();9076 const syscall: Syscall = try .start();
9106 while (true) {9077 while (true) {
9107 const rc = ws2_32.listen(socket_handle, options.kernel_backlog);9078 const rc = ws2_32.listen(socket_handle, options.kernel_backlog);
9108 if (rc != ws2_32.SOCKET_ERROR) {9079 if (rc != ws2_32.SOCKET_ERROR) {
9109 current_thread.endSyscall();9080 syscall.finish();
9110 break;9081 break;
9111 }9082 }
9112 switch (ws2_32.WSAGetLastError()) {9083 switch (ws2_32.WSAGetLastError()) {
9113 .EINTR => {9084 .EINTR => {
9114 try current_thread.checkCancel();9085 try syscall.checkCancel();
9115 continue;9086 continue;
9116 },9087 },
9117 .NOTINITIALISED => {9088 .NOTINITIALISED => {
9118 try initializeWsa(t);9089 try initializeWsa(t);
9119 try current_thread.checkCancel();9090 try syscall.checkCancel();
9120 continue;9091 continue;
9121 },9092 },
9122 else => |e| {9093 else => |e| {
9123 current_thread.endSyscall();9094 syscall.finish();
9124 switch (e) {9095 switch (e) {
9125 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,9096 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
9126 .ENETDOWN => return error.NetworkDown,9097 .ENETDOWN => return error.NetworkDown,
9127 .EADDRINUSE => return error.AddressInUse,9098 .EADDRINUSE => return error.AddressInUse,
9128 .EISCONN => |err| return wsaErrorBug(err),9099 .EISCONN => |err| return wsaErrorBug(err),
9129 .EINVAL => |err| return wsaErrorBug(err),9100 .EINVAL => |err| return wsaErrorBug(err),
9130 .EMFILE, .ENOBUFS => return error.SystemResources,9101 .EMFILE, .ENOBUFS => return error.SystemResources,
9131 .ENOTSOCK => |err| return wsaErrorBug(err),9102 .ENOTSOCK => |err| return wsaErrorBug(err),
9132 .EOPNOTSUPP => |err| return wsaErrorBug(err),9103 .EOPNOTSUPP => |err| return wsaErrorBug(err),
9133 .EINPROGRESS => |err| return wsaErrorBug(err),9104 .EINPROGRESS => |err| return wsaErrorBug(err),
9134 else => |err| return windows.unexpectedWSAError(err),9105 else => |err| return windows.unexpectedWSAError(err),
9135 }9106 }
9136 },9107 },
9108 }
9137 }9109 }
9138 }9110 }
91399111
9140 try wsaGetSockName(t, current_thread, socket_handle, &storage.any, &addr_len);9112 try wsaGetSockName(t, socket_handle, &storage.any, &addr_len);
91419113
9142 return .{9114 return .{
9143 .socket = .{9115 .socket = .{
...@@ -9165,8 +9137,8 @@ fn netListenUnixPosix(...@@ -9165,8 +9137,8 @@ fn netListenUnixPosix(
9165) net.UnixAddress.ListenError!net.Socket.Handle {9137) net.UnixAddress.ListenError!net.Socket.Handle {
9166 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;9138 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
9167 const t: *Threaded = @ptrCast(@alignCast(userdata));9139 const t: *Threaded = @ptrCast(@alignCast(userdata));
9168 const current_thread = Thread.getCurrent(t);9140 _ = t;
9169 const socket_fd = openSocketPosix(current_thread, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {9141 const socket_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
9170 error.ProtocolUnsupportedBySystem => return error.AddressFamilyUnsupported,9142 error.ProtocolUnsupportedBySystem => return error.AddressFamilyUnsupported,
9171 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,9143 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
9172 error.SocketModeUnsupported => return error.AddressFamilyUnsupported,9144 error.SocketModeUnsupported => return error.AddressFamilyUnsupported,
...@@ -9177,21 +9149,21 @@ fn netListenUnixPosix(...@@ -9177,21 +9149,21 @@ fn netListenUnixPosix(
91779149
9178 var storage: UnixAddress = undefined;9150 var storage: UnixAddress = undefined;
9179 const addr_len = addressUnixToPosix(address, &storage);9151 const addr_len = addressUnixToPosix(address, &storage);
9180 try posixBindUnix(current_thread, socket_fd, &storage.any, addr_len);9152 try posixBindUnix(socket_fd, &storage.any, addr_len);
91819153
9182 try current_thread.beginSyscall();9154 const syscall: Syscall = try .start();
9183 while (true) {9155 while (true) {
9184 switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {9156 switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {
9185 .SUCCESS => {9157 .SUCCESS => {
9186 current_thread.endSyscall();9158 syscall.finish();
9187 break;9159 break;
9188 },9160 },
9189 .INTR => {9161 .INTR => {
9190 try current_thread.checkCancel();9162 try syscall.checkCancel();
9191 continue;9163 continue;
9192 },9164 },
9193 else => |e| {9165 else => |e| {
9194 current_thread.endSyscall();9166 syscall.finish();
9195 switch (e) {9167 switch (e) {
9196 .ADDRINUSE => return error.AddressInUse,9168 .ADDRINUSE => return error.AddressInUse,
9197 .BADF => |err| return errnoBug(err), // File descriptor used after closed.9169 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -9211,9 +9183,8 @@ fn netListenUnixWindows(...@@ -9211,9 +9183,8 @@ fn netListenUnixWindows(
9211) net.UnixAddress.ListenError!net.Socket.Handle {9183) net.UnixAddress.ListenError!net.Socket.Handle {
9212 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;9184 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
9213 const t: *Threaded = @ptrCast(@alignCast(userdata));9185 const t: *Threaded = @ptrCast(@alignCast(userdata));
9214 const current_thread = Thread.getCurrent(t);
92159186
9216 const socket_handle = openSocketWsa(t, current_thread, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {9187 const socket_handle = openSocketWsa(t, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
9217 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,9188 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
9218 else => |e| return e,9189 else => |e| return e,
9219 };9190 };
...@@ -9222,22 +9193,22 @@ fn netListenUnixWindows(...@@ -9222,22 +9193,22 @@ fn netListenUnixWindows(
9222 var storage: WsaAddress = undefined;9193 var storage: WsaAddress = undefined;
9223 const addr_len = addressUnixToWsa(address, &storage);9194 const addr_len = addressUnixToWsa(address, &storage);
92249195
9225 try current_thread.beginSyscall();9196 const syscall: Syscall = try .start();
9226 while (true) {9197 while (true) {
9227 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);9198 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
9228 if (rc != ws2_32.SOCKET_ERROR) break;9199 if (rc != ws2_32.SOCKET_ERROR) break;
9229 switch (ws2_32.WSAGetLastError()) {9200 switch (ws2_32.WSAGetLastError()) {
9230 .EINTR => {9201 .EINTR => {
9231 try current_thread.checkCancel();9202 try syscall.checkCancel();
9232 continue;9203 continue;
9233 },9204 },
9234 .NOTINITIALISED => {9205 .NOTINITIALISED => {
9235 try initializeWsa(t);9206 try initializeWsa(t);
9236 try current_thread.checkCancel();9207 try syscall.checkCancel();
9237 continue;9208 continue;
9238 },9209 },
9239 else => |e| {9210 else => |e| {
9240 current_thread.endSyscall();9211 syscall.finish();
9241 switch (e) {9212 switch (e) {
9242 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,9213 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
9243 .EADDRINUSE => return error.AddressInUse,9214 .EADDRINUSE => return error.AddressInUse,
...@@ -9254,10 +9225,10 @@ fn netListenUnixWindows(...@@ -9254,10 +9225,10 @@ fn netListenUnixWindows(
9254 }9225 }
92559226
9256 while (true) {9227 while (true) {
9257 try current_thread.checkCancel();9228 try syscall.checkCancel();
9258 const rc = ws2_32.listen(socket_handle, options.kernel_backlog);9229 const rc = ws2_32.listen(socket_handle, options.kernel_backlog);
9259 if (rc != ws2_32.SOCKET_ERROR) {9230 if (rc != ws2_32.SOCKET_ERROR) {
9260 current_thread.endSyscall();9231 syscall.finish();
9261 return socket_handle;9232 return socket_handle;
9262 }9233 }
9263 switch (ws2_32.WSAGetLastError()) {9234 switch (ws2_32.WSAGetLastError()) {
...@@ -9267,7 +9238,7 @@ fn netListenUnixWindows(...@@ -9267,7 +9238,7 @@ fn netListenUnixWindows(
9267 continue;9238 continue;
9268 },9239 },
9269 else => |e| {9240 else => |e| {
9270 current_thread.endSyscall();9241 syscall.finish();
9271 switch (e) {9242 switch (e) {
9272 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,9243 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
9273 .ENETDOWN => return error.NetworkDown,9244 .ENETDOWN => return error.NetworkDown,
...@@ -9297,24 +9268,23 @@ fn netListenUnixUnavailable(...@@ -9297,24 +9268,23 @@ fn netListenUnixUnavailable(
9297}9268}
92989269
9299fn posixBindUnix(9270fn posixBindUnix(
9300 current_thread: *Thread,
9301 fd: posix.socket_t,9271 fd: posix.socket_t,
9302 addr: *const posix.sockaddr,9272 addr: *const posix.sockaddr,
9303 addr_len: posix.socklen_t,9273 addr_len: posix.socklen_t,
9304) !void {9274) !void {
9305 try current_thread.beginSyscall();9275 const syscall: Syscall = try .start();
9306 while (true) {9276 while (true) {
9307 switch (posix.errno(posix.system.bind(fd, addr, addr_len))) {9277 switch (posix.errno(posix.system.bind(fd, addr, addr_len))) {
9308 .SUCCESS => {9278 .SUCCESS => {
9309 current_thread.endSyscall();9279 syscall.finish();
9310 break;9280 break;
9311 },9281 },
9312 .INTR => {9282 .INTR => {
9313 try current_thread.checkCancel();9283 try syscall.checkCancel();
9314 continue;9284 continue;
9315 },9285 },
9316 else => |e| {9286 else => |e| {
9317 current_thread.endSyscall();9287 syscall.finish();
9318 switch (e) {9288 switch (e) {
9319 .ACCES => return error.AccessDenied,9289 .ACCES => return error.AccessDenied,
9320 .ADDRINUSE => return error.AddressInUse,9290 .ADDRINUSE => return error.AddressInUse,
...@@ -9341,24 +9311,23 @@ fn posixBindUnix(...@@ -9341,24 +9311,23 @@ fn posixBindUnix(
9341}9311}
93429312
9343fn posixBind(9313fn posixBind(
9344 current_thread: *Thread,
9345 socket_fd: posix.socket_t,9314 socket_fd: posix.socket_t,
9346 addr: *const posix.sockaddr,9315 addr: *const posix.sockaddr,
9347 addr_len: posix.socklen_t,9316 addr_len: posix.socklen_t,
9348) !void {9317) !void {
9349 try current_thread.beginSyscall();9318 const syscall: Syscall = try .start();
9350 while (true) {9319 while (true) {
9351 switch (posix.errno(posix.system.bind(socket_fd, addr, addr_len))) {9320 switch (posix.errno(posix.system.bind(socket_fd, addr, addr_len))) {
9352 .SUCCESS => {9321 .SUCCESS => {
9353 current_thread.endSyscall();9322 syscall.finish();
9354 break;9323 break;
9355 },9324 },
9356 .INTR => {9325 .INTR => {
9357 try current_thread.checkCancel();9326 try syscall.checkCancel();
9358 continue;9327 continue;
9359 },9328 },
9360 else => |e| {9329 else => |e| {
9361 current_thread.endSyscall();9330 syscall.finish();
9362 switch (e) {9331 switch (e) {
9363 .ADDRINUSE => return error.AddressInUse,9332 .ADDRINUSE => return error.AddressInUse,
9364 .BADF => |err| return errnoBug(err), // File descriptor used after closed.9333 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -9376,24 +9345,23 @@ fn posixBind(...@@ -9376,24 +9345,23 @@ fn posixBind(
9376}9345}
93779346
9378fn posixConnect(9347fn posixConnect(
9379 current_thread: *Thread,
9380 socket_fd: posix.socket_t,9348 socket_fd: posix.socket_t,
9381 addr: *const posix.sockaddr,9349 addr: *const posix.sockaddr,
9382 addr_len: posix.socklen_t,9350 addr_len: posix.socklen_t,
9383) !void {9351) !void {
9384 try current_thread.beginSyscall();9352 const syscall: Syscall = try .start();
9385 while (true) {9353 while (true) {
9386 switch (posix.errno(posix.system.connect(socket_fd, addr, addr_len))) {9354 switch (posix.errno(posix.system.connect(socket_fd, addr, addr_len))) {
9387 .SUCCESS => {9355 .SUCCESS => {
9388 current_thread.endSyscall();9356 syscall.finish();
9389 return;9357 return;
9390 },9358 },
9391 .INTR => {9359 .INTR => {
9392 try current_thread.checkCancel();9360 try syscall.checkCancel();
9393 continue;9361 continue;
9394 },9362 },
9395 else => |e| {9363 else => |e| {
9396 current_thread.endSyscall();9364 syscall.finish();
9397 switch (e) {9365 switch (e) {
9398 .ADDRNOTAVAIL => return error.AddressUnavailable,9366 .ADDRNOTAVAIL => return error.AddressUnavailable,
9399 .AFNOSUPPORT => return error.AddressFamilyUnsupported,9367 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
...@@ -9422,24 +9390,23 @@ fn posixConnect(...@@ -9422,24 +9390,23 @@ fn posixConnect(
9422}9390}
94239391
9424fn posixConnectUnix(9392fn posixConnectUnix(
9425 current_thread: *Thread,
9426 fd: posix.socket_t,9393 fd: posix.socket_t,
9427 addr: *const posix.sockaddr,9394 addr: *const posix.sockaddr,
9428 addr_len: posix.socklen_t,9395 addr_len: posix.socklen_t,
9429) !void {9396) !void {
9430 try current_thread.beginSyscall();9397 const syscall: Syscall = try .start();
9431 while (true) {9398 while (true) {
9432 switch (posix.errno(posix.system.connect(fd, addr, addr_len))) {9399 switch (posix.errno(posix.system.connect(fd, addr, addr_len))) {
9433 .SUCCESS => {9400 .SUCCESS => {
9434 current_thread.endSyscall();9401 syscall.finish();
9435 return;9402 return;
9436 },9403 },
9437 .INTR => {9404 .INTR => {
9438 try current_thread.checkCancel();9405 try syscall.checkCancel();
9439 continue;9406 continue;
9440 },9407 },
9441 else => |e| {9408 else => |e| {
9442 current_thread.endSyscall();9409 syscall.finish();
9443 switch (e) {9410 switch (e) {
9444 .AFNOSUPPORT => return error.AddressFamilyUnsupported,9411 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
9445 .AGAIN => return error.WouldBlock,9412 .AGAIN => return error.WouldBlock,
...@@ -9466,24 +9433,23 @@ fn posixConnectUnix(...@@ -9466,24 +9433,23 @@ fn posixConnectUnix(
9466}9433}
94679434
9468fn posixGetSockName(9435fn posixGetSockName(
9469 current_thread: *Thread,
9470 socket_fd: posix.fd_t,9436 socket_fd: posix.fd_t,
9471 addr: *posix.sockaddr,9437 addr: *posix.sockaddr,
9472 addr_len: *posix.socklen_t,9438 addr_len: *posix.socklen_t,
9473) !void {9439) !void {
9474 try current_thread.beginSyscall();9440 const syscall: Syscall = try .start();
9475 while (true) {9441 while (true) {
9476 switch (posix.errno(posix.system.getsockname(socket_fd, addr, addr_len))) {9442 switch (posix.errno(posix.system.getsockname(socket_fd, addr, addr_len))) {
9477 .SUCCESS => {9443 .SUCCESS => {
9478 current_thread.endSyscall();9444 syscall.finish();
9479 break;9445 break;
9480 },9446 },
9481 .INTR => {9447 .INTR => {
9482 try current_thread.checkCancel();9448 try syscall.checkCancel();
9483 continue;9449 continue;
9484 },9450 },
9485 else => |e| {9451 else => |e| {
9486 current_thread.endSyscall();9452 syscall.finish();
9487 switch (e) {9453 switch (e) {
9488 .BADF => |err| return errnoBug(err), // File descriptor used after closed.9454 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
9489 .FAULT => |err| return errnoBug(err),9455 .FAULT => |err| return errnoBug(err),
...@@ -9499,30 +9465,29 @@ fn posixGetSockName(...@@ -9499,30 +9465,29 @@ fn posixGetSockName(
94999465
9500fn wsaGetSockName(9466fn wsaGetSockName(
9501 t: *Threaded,9467 t: *Threaded,
9502 current_thread: *Thread,
9503 handle: ws2_32.SOCKET,9468 handle: ws2_32.SOCKET,
9504 addr: *ws2_32.sockaddr,9469 addr: *ws2_32.sockaddr,
9505 addr_len: *i32,9470 addr_len: *i32,
9506) !void {9471) !void {
9507 try current_thread.beginSyscall();9472 const syscall: Syscall = try .start();
9508 while (true) {9473 while (true) {
9509 const rc = ws2_32.getsockname(handle, addr, addr_len);9474 const rc = ws2_32.getsockname(handle, addr, addr_len);
9510 if (rc != ws2_32.SOCKET_ERROR) {9475 if (rc != ws2_32.SOCKET_ERROR) {
9511 current_thread.endSyscall();9476 syscall.finish();
9512 return;9477 return;
9513 }9478 }
9514 switch (ws2_32.WSAGetLastError()) {9479 switch (ws2_32.WSAGetLastError()) {
9515 .EINTR => {9480 .EINTR => {
9516 try current_thread.checkCancel();9481 try syscall.checkCancel();
9517 continue;9482 continue;
9518 },9483 },
9519 .NOTINITIALISED => {9484 .NOTINITIALISED => {
9520 try initializeWsa(t);9485 try initializeWsa(t);
9521 try current_thread.checkCancel();9486 try syscall.checkCancel();
9522 continue;9487 continue;
9523 },9488 },
9524 else => |e| {9489 else => |e| {
9525 current_thread.endSyscall();9490 syscall.finish();
9526 switch (e) {9491 switch (e) {
9527 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,9492 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
9528 .ENETDOWN => return error.NetworkDown,9493 .ENETDOWN => return error.NetworkDown,
...@@ -9536,21 +9501,21 @@ fn wsaGetSockName(...@@ -9536,21 +9501,21 @@ fn wsaGetSockName(
9536 }9501 }
9537}9502}
95389503
9539fn setSocketOption(current_thread: *Thread, fd: posix.fd_t, level: i32, opt_name: u32, option: u32) !void {9504fn setSocketOption(fd: posix.fd_t, level: i32, opt_name: u32, option: u32) !void {
9540 const o: []const u8 = @ptrCast(&option);9505 const o: []const u8 = @ptrCast(&option);
9541 try current_thread.beginSyscall();9506 const syscall: Syscall = try .start();
9542 while (true) {9507 while (true) {
9543 switch (posix.errno(posix.system.setsockopt(fd, level, opt_name, o.ptr, @intCast(o.len)))) {9508 switch (posix.errno(posix.system.setsockopt(fd, level, opt_name, o.ptr, @intCast(o.len)))) {
9544 .SUCCESS => {9509 .SUCCESS => {
9545 current_thread.endSyscall();9510 syscall.finish();
9546 return;9511 return;
9547 },9512 },
9548 .INTR => {9513 .INTR => {
9549 try current_thread.checkCancel();9514 try syscall.checkCancel();
9550 continue;9515 continue;
9551 },9516 },
9552 else => |e| {9517 else => |e| {
9553 current_thread.endSyscall();9518 syscall.finish();
9554 switch (e) {9519 switch (e) {
9555 .BADF => |err| return errnoBug(err), // File descriptor used after closed.9520 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
9556 .NOTSOCK => |err| return errnoBug(err),9521 .NOTSOCK => |err| return errnoBug(err),
...@@ -9592,17 +9557,17 @@ fn netConnectIpPosix(...@@ -9592,17 +9557,17 @@ fn netConnectIpPosix(
9592 if (!have_networking) return error.NetworkDown;9557 if (!have_networking) return error.NetworkDown;
9593 if (options.timeout != .none) @panic("TODO implement netConnectIpPosix with timeout");9558 if (options.timeout != .none) @panic("TODO implement netConnectIpPosix with timeout");
9594 const t: *Threaded = @ptrCast(@alignCast(userdata));9559 const t: *Threaded = @ptrCast(@alignCast(userdata));
9595 const current_thread = Thread.getCurrent(t);9560 _ = t;
9596 const family = posixAddressFamily(address);9561 const family = posixAddressFamily(address);
9597 const socket_fd = try openSocketPosix(current_thread, family, .{9562 const socket_fd = try openSocketPosix(family, .{
9598 .mode = options.mode,9563 .mode = options.mode,
9599 .protocol = options.protocol,9564 .protocol = options.protocol,
9600 });9565 });
9601 errdefer posix.close(socket_fd);9566 errdefer posix.close(socket_fd);
9602 var storage: PosixAddress = undefined;9567 var storage: PosixAddress = undefined;
9603 var addr_len = addressToPosix(address, &storage);9568 var addr_len = addressToPosix(address, &storage);
9604 try posixConnect(current_thread, socket_fd, &storage.any, addr_len);9569 try posixConnect(socket_fd, &storage.any, addr_len);
9605 try posixGetSockName(current_thread, socket_fd, &storage.any, &addr_len);9570 try posixGetSockName(socket_fd, &storage.any, &addr_len);
9606 return .{ .socket = .{9571 return .{ .socket = .{
9607 .handle = socket_fd,9572 .handle = socket_fd,
9608 .address = addressFromPosix(&storage),9573 .address = addressFromPosix(&storage),
...@@ -9617,9 +9582,8 @@ fn netConnectIpWindows(...@@ -9617,9 +9582,8 @@ fn netConnectIpWindows(
9617 if (!have_networking) return error.NetworkDown;9582 if (!have_networking) return error.NetworkDown;
9618 if (options.timeout != .none) @panic("TODO implement netConnectIpWindows with timeout");9583 if (options.timeout != .none) @panic("TODO implement netConnectIpWindows with timeout");
9619 const t: *Threaded = @ptrCast(@alignCast(userdata));9584 const t: *Threaded = @ptrCast(@alignCast(userdata));
9620 const current_thread = Thread.getCurrent(t);
9621 const family = posixAddressFamily(address);9585 const family = posixAddressFamily(address);
9622 const socket_handle = try openSocketWsa(t, current_thread, family, .{9586 const socket_handle = try openSocketWsa(t, family, .{
9623 .mode = options.mode,9587 .mode = options.mode,
9624 .protocol = options.protocol,9588 .protocol = options.protocol,
9625 });9589 });
...@@ -9628,25 +9592,25 @@ fn netConnectIpWindows(...@@ -9628,25 +9592,25 @@ fn netConnectIpWindows(
9628 var storage: WsaAddress = undefined;9592 var storage: WsaAddress = undefined;
9629 var addr_len = addressToWsa(address, &storage);9593 var addr_len = addressToWsa(address, &storage);
96309594
9631 try current_thread.beginSyscall();9595 const syscall: Syscall = try .start();
9632 while (true) {9596 while (true) {
9633 const rc = ws2_32.connect(socket_handle, &storage.any, addr_len);9597 const rc = ws2_32.connect(socket_handle, &storage.any, addr_len);
9634 if (rc != ws2_32.SOCKET_ERROR) {9598 if (rc != ws2_32.SOCKET_ERROR) {
9635 current_thread.endSyscall();9599 syscall.finish();
9636 break;9600 break;
9637 }9601 }
9638 switch (ws2_32.WSAGetLastError()) {9602 switch (ws2_32.WSAGetLastError()) {
9639 .EINTR => {9603 .EINTR => {
9640 try current_thread.checkCancel();9604 try syscall.checkCancel();
9641 continue;9605 continue;
9642 },9606 },
9643 .NOTINITIALISED => {9607 .NOTINITIALISED => {
9644 try initializeWsa(t);9608 try initializeWsa(t);
9645 try current_thread.checkCancel();9609 try syscall.checkCancel();
9646 continue;9610 continue;
9647 },9611 },
9648 else => |e| {9612 else => |e| {
9649 current_thread.endSyscall();9613 syscall.finish();
9650 switch (e) {9614 switch (e) {
9651 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,9615 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
9652 .EADDRNOTAVAIL => return error.AddressUnavailable,9616 .EADDRNOTAVAIL => return error.AddressUnavailable,
...@@ -9669,7 +9633,7 @@ fn netConnectIpWindows(...@@ -9669,7 +9633,7 @@ fn netConnectIpWindows(
9669 }9633 }
9670 }9634 }
96719635
9672 try wsaGetSockName(t, current_thread, socket_handle, &storage.any, &addr_len);9636 try wsaGetSockName(t, socket_handle, &storage.any, &addr_len);
96739637
9674 return .{ .socket = .{9638 return .{ .socket = .{
9675 .handle = socket_handle,9639 .handle = socket_handle,
...@@ -9694,15 +9658,15 @@ fn netConnectUnixPosix(...@@ -9694,15 +9658,15 @@ fn netConnectUnixPosix(
9694) net.UnixAddress.ConnectError!net.Socket.Handle {9658) net.UnixAddress.ConnectError!net.Socket.Handle {
9695 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;9659 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
9696 const t: *Threaded = @ptrCast(@alignCast(userdata));9660 const t: *Threaded = @ptrCast(@alignCast(userdata));
9697 const current_thread = Thread.getCurrent(t);9661 _ = t;
9698 const socket_fd = openSocketPosix(current_thread, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {9662 const socket_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
9699 error.OptionUnsupported => return error.Unexpected,9663 error.OptionUnsupported => return error.Unexpected,
9700 else => |e| return e,9664 else => |e| return e,
9701 };9665 };
9702 errdefer posix.close(socket_fd);9666 errdefer posix.close(socket_fd);
9703 var storage: UnixAddress = undefined;9667 var storage: UnixAddress = undefined;
9704 const addr_len = addressUnixToPosix(address, &storage);9668 const addr_len = addressUnixToPosix(address, &storage);
9705 try posixConnectUnix(current_thread, socket_fd, &storage.any, addr_len);9669 try posixConnectUnix(socket_fd, &storage.any, addr_len);
9706 return socket_fd;9670 return socket_fd;
9707}9671}
97089672
...@@ -9712,9 +9676,8 @@ fn netConnectUnixWindows(...@@ -9712,9 +9676,8 @@ fn netConnectUnixWindows(
9712) net.UnixAddress.ConnectError!net.Socket.Handle {9676) net.UnixAddress.ConnectError!net.Socket.Handle {
9713 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;9677 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
9714 const t: *Threaded = @ptrCast(@alignCast(userdata));9678 const t: *Threaded = @ptrCast(@alignCast(userdata));
9715 const current_thread = Thread.getCurrent(t);
97169679
9717 const socket_handle = try openSocketWsa(t, current_thread, posix.AF.UNIX, .{ .mode = .stream });9680 const socket_handle = try openSocketWsa(t, posix.AF.UNIX, .{ .mode = .stream });
9718 errdefer closeSocketWindows(socket_handle);9681 errdefer closeSocketWindows(socket_handle);
9719 var storage: WsaAddress = undefined;9682 var storage: WsaAddress = undefined;
9720 const addr_len = addressUnixToWsa(address, &storage);9683 const addr_len = addressUnixToWsa(address, &storage);
...@@ -9762,14 +9725,14 @@ fn netBindIpPosix(...@@ -9762,14 +9725,14 @@ fn netBindIpPosix(
9762) IpAddress.BindError!net.Socket {9725) IpAddress.BindError!net.Socket {
9763 if (!have_networking) return error.NetworkDown;9726 if (!have_networking) return error.NetworkDown;
9764 const t: *Threaded = @ptrCast(@alignCast(userdata));9727 const t: *Threaded = @ptrCast(@alignCast(userdata));
9765 const current_thread = Thread.getCurrent(t);9728 _ = t;
9766 const family = posixAddressFamily(address);9729 const family = posixAddressFamily(address);
9767 const socket_fd = try openSocketPosix(current_thread, family, options);9730 const socket_fd = try openSocketPosix(family, options);
9768 errdefer posix.close(socket_fd);9731 errdefer posix.close(socket_fd);
9769 var storage: PosixAddress = undefined;9732 var storage: PosixAddress = undefined;
9770 var addr_len = addressToPosix(address, &storage);9733 var addr_len = addressToPosix(address, &storage);
9771 try posixBind(current_thread, socket_fd, &storage.any, addr_len);9734 try posixBind(socket_fd, &storage.any, addr_len);
9772 try posixGetSockName(current_thread, socket_fd, &storage.any, &addr_len);9735 try posixGetSockName(socket_fd, &storage.any, &addr_len);
9773 return .{9736 return .{
9774 .handle = socket_fd,9737 .handle = socket_fd,
9775 .address = addressFromPosix(&storage),9738 .address = addressFromPosix(&storage),
...@@ -9783,9 +9746,8 @@ fn netBindIpWindows(...@@ -9783,9 +9746,8 @@ fn netBindIpWindows(
9783) IpAddress.BindError!net.Socket {9746) IpAddress.BindError!net.Socket {
9784 if (!have_networking) return error.NetworkDown;9747 if (!have_networking) return error.NetworkDown;
9785 const t: *Threaded = @ptrCast(@alignCast(userdata));9748 const t: *Threaded = @ptrCast(@alignCast(userdata));
9786 const current_thread = Thread.getCurrent(t);
9787 const family = posixAddressFamily(address);9749 const family = posixAddressFamily(address);
9788 const socket_handle = try openSocketWsa(t, current_thread, family, .{9750 const socket_handle = try openSocketWsa(t, family, .{
9789 .mode = options.mode,9751 .mode = options.mode,
9790 .protocol = options.protocol,9752 .protocol = options.protocol,
9791 });9753 });
...@@ -9794,25 +9756,25 @@ fn netBindIpWindows(...@@ -9794,25 +9756,25 @@ fn netBindIpWindows(
9794 var storage: WsaAddress = undefined;9756 var storage: WsaAddress = undefined;
9795 var addr_len = addressToWsa(address, &storage);9757 var addr_len = addressToWsa(address, &storage);
97969758
9797 try current_thread.beginSyscall();9759 const syscall: Syscall = try .start();
9798 while (true) {9760 while (true) {
9799 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);9761 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
9800 if (rc != ws2_32.SOCKET_ERROR) {9762 if (rc != ws2_32.SOCKET_ERROR) {
9801 current_thread.endSyscall();9763 syscall.finish();
9802 break;9764 break;
9803 }9765 }
9804 switch (ws2_32.WSAGetLastError()) {9766 switch (ws2_32.WSAGetLastError()) {
9805 .EINTR => {9767 .EINTR => {
9806 try current_thread.checkCancel();9768 try syscall.checkCancel();
9807 continue;9769 continue;
9808 },9770 },
9809 .NOTINITIALISED => {9771 .NOTINITIALISED => {
9810 try initializeWsa(t);9772 try initializeWsa(t);
9811 try current_thread.checkCancel();9773 try syscall.checkCancel();
9812 continue;9774 continue;
9813 },9775 },
9814 else => |e| {9776 else => |e| {
9815 current_thread.endSyscall();9777 syscall.finish();
9816 switch (e) {9778 switch (e) {
9817 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,9779 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
9818 .EADDRINUSE => return error.AddressInUse,9780 .EADDRINUSE => return error.AddressInUse,
...@@ -9828,7 +9790,7 @@ fn netBindIpWindows(...@@ -9828,7 +9790,7 @@ fn netBindIpWindows(
9828 }9790 }
9829 }9791 }
98309792
9831 try wsaGetSockName(t, current_thread, socket_handle, &storage.any, &addr_len);9793 try wsaGetSockName(t, socket_handle, &storage.any, &addr_len);
98329794
9833 return .{9795 return .{
9834 .handle = socket_handle,9796 .handle = socket_handle,
...@@ -9848,7 +9810,6 @@ fn netBindIpUnavailable(...@@ -9848,7 +9810,6 @@ fn netBindIpUnavailable(
9848}9810}
98499811
9850fn openSocketPosix(9812fn openSocketPosix(
9851 current_thread: *Thread,
9852 family: posix.sa_family_t,9813 family: posix.sa_family_t,
9853 options: IpAddress.BindOptions,9814 options: IpAddress.BindOptions,
9854) error{9815) error{
...@@ -9865,7 +9826,7 @@ fn openSocketPosix(...@@ -9865,7 +9826,7 @@ fn openSocketPosix(
9865}!posix.socket_t {9826}!posix.socket_t {
9866 const mode = posixSocketMode(options.mode);9827 const mode = posixSocketMode(options.mode);
9867 const protocol = posixProtocol(options.protocol);9828 const protocol = posixProtocol(options.protocol);
9868 try current_thread.beginSyscall();9829 const syscall: Syscall = try .start();
9869 const socket_fd = while (true) {9830 const socket_fd = while (true) {
9870 const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;9831 const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;
9871 const socket_rc = posix.system.socket(family, flags, protocol);9832 const socket_rc = posix.system.socket(family, flags, protocol);
...@@ -9874,25 +9835,25 @@ fn openSocketPosix(...@@ -9874,25 +9835,25 @@ fn openSocketPosix(
9874 const fd: posix.fd_t = @intCast(socket_rc);9835 const fd: posix.fd_t = @intCast(socket_rc);
9875 errdefer posix.close(fd);9836 errdefer posix.close(fd);
9876 if (socket_flags_unsupported) while (true) {9837 if (socket_flags_unsupported) while (true) {
9877 try current_thread.checkCancel();9838 try syscall.checkCancel();
9878 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {9839 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
9879 .SUCCESS => break,9840 .SUCCESS => break,
9880 .INTR => continue,9841 .INTR => continue,
9881 else => |err| {9842 else => |err| {
9882 current_thread.endSyscall();9843 syscall.finish();
9883 return posix.unexpectedErrno(err);9844 return posix.unexpectedErrno(err);
9884 },9845 },
9885 }9846 }
9886 };9847 };
9887 current_thread.endSyscall();9848 syscall.finish();
9888 break fd;9849 break fd;
9889 },9850 },
9890 .INTR => {9851 .INTR => {
9891 try current_thread.checkCancel();9852 try syscall.checkCancel();
9892 continue;9853 continue;
9893 },9854 },
9894 else => |e| {9855 else => |e| {
9895 current_thread.endSyscall();9856 syscall.finish();
9896 switch (e) {9857 switch (e) {
9897 .AFNOSUPPORT => return error.AddressFamilyUnsupported,9858 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
9898 .INVAL => return error.ProtocolUnsupportedBySystem,9859 .INVAL => return error.ProtocolUnsupportedBySystem,
...@@ -9911,7 +9872,7 @@ fn openSocketPosix(...@@ -9911,7 +9872,7 @@ fn openSocketPosix(
99119872
9912 if (options.ip6_only) {9873 if (options.ip6_only) {
9913 if (posix.IPV6 == void) return error.OptionUnsupported;9874 if (posix.IPV6 == void) return error.OptionUnsupported;
9914 try setSocketOption(current_thread, socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, 0);9875 try setSocketOption(socket_fd, posix.IPPROTO.IPV6, posix.IPV6.V6ONLY, 0);
9915 }9876 }
99169877
9917 return socket_fd;9878 return socket_fd;
...@@ -9919,32 +9880,31 @@ fn openSocketPosix(...@@ -9919,32 +9880,31 @@ fn openSocketPosix(
99199880
9920fn openSocketWsa(9881fn openSocketWsa(
9921 t: *Threaded,9882 t: *Threaded,
9922 current_thread: *Thread,
9923 family: posix.sa_family_t,9883 family: posix.sa_family_t,
9924 options: IpAddress.BindOptions,9884 options: IpAddress.BindOptions,
9925) !ws2_32.SOCKET {9885) !ws2_32.SOCKET {
9926 const mode = posixSocketMode(options.mode);9886 const mode = posixSocketMode(options.mode);
9927 const protocol = posixProtocol(options.protocol);9887 const protocol = posixProtocol(options.protocol);
9928 const flags: u32 = ws2_32.WSA_FLAG_OVERLAPPED | ws2_32.WSA_FLAG_NO_HANDLE_INHERIT;9888 const flags: u32 = ws2_32.WSA_FLAG_OVERLAPPED | ws2_32.WSA_FLAG_NO_HANDLE_INHERIT;
9929 try current_thread.beginSyscall();9889 const syscall: Syscall = try .start();
9930 while (true) {9890 while (true) {
9931 const rc = ws2_32.WSASocketW(family, @bitCast(mode), @bitCast(protocol), null, 0, flags);9891 const rc = ws2_32.WSASocketW(family, @bitCast(mode), @bitCast(protocol), null, 0, flags);
9932 if (rc != ws2_32.INVALID_SOCKET) {9892 if (rc != ws2_32.INVALID_SOCKET) {
9933 current_thread.endSyscall();9893 syscall.finish();
9934 return rc;9894 return rc;
9935 }9895 }
9936 switch (ws2_32.WSAGetLastError()) {9896 switch (ws2_32.WSAGetLastError()) {
9937 .EINTR => {9897 .EINTR => {
9938 try current_thread.checkCancel();9898 try syscall.checkCancel();
9939 continue;9899 continue;
9940 },9900 },
9941 .NOTINITIALISED => {9901 .NOTINITIALISED => {
9942 try initializeWsa(t);9902 try initializeWsa(t);
9943 try current_thread.checkCancel();9903 try syscall.checkCancel();
9944 continue;9904 continue;
9945 },9905 },
9946 else => |e| {9906 else => |e| {
9947 current_thread.endSyscall();9907 syscall.finish();
9948 switch (e) {9908 switch (e) {
9949 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,9909 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
9950 .EAFNOSUPPORT => return error.AddressFamilyUnsupported,9910 .EAFNOSUPPORT => return error.AddressFamilyUnsupported,
...@@ -9961,10 +9921,10 @@ fn openSocketWsa(...@@ -9961,10 +9921,10 @@ fn openSocketWsa(
9961fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Server.AcceptError!net.Stream {9921fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Server.AcceptError!net.Stream {
9962 if (!have_networking) return error.NetworkDown;9922 if (!have_networking) return error.NetworkDown;
9963 const t: *Threaded = @ptrCast(@alignCast(userdata));9923 const t: *Threaded = @ptrCast(@alignCast(userdata));
9964 const current_thread = Thread.getCurrent(t);9924 _ = t;
9965 var storage: PosixAddress = undefined;9925 var storage: PosixAddress = undefined;
9966 var addr_len: posix.socklen_t = @sizeOf(PosixAddress);9926 var addr_len: posix.socklen_t = @sizeOf(PosixAddress);
9967 try current_thread.beginSyscall();9927 const syscall: Syscall = try .start();
9968 const fd = while (true) {9928 const fd = while (true) {
9969 const rc = if (have_accept4)9929 const rc = if (have_accept4)
9970 posix.system.accept4(listen_fd, &storage.any, &addr_len, posix.SOCK.CLOEXEC)9930 posix.system.accept4(listen_fd, &storage.any, &addr_len, posix.SOCK.CLOEXEC)
...@@ -9975,25 +9935,25 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve...@@ -9975,25 +9935,25 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
9975 const fd: posix.fd_t = @intCast(rc);9935 const fd: posix.fd_t = @intCast(rc);
9976 errdefer posix.close(fd);9936 errdefer posix.close(fd);
9977 if (!have_accept4) while (true) {9937 if (!have_accept4) while (true) {
9978 try current_thread.checkCancel();9938 try syscall.checkCancel();
9979 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {9939 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
9980 .SUCCESS => break,9940 .SUCCESS => break,
9981 .INTR => continue,9941 .INTR => continue,
9982 else => |err| {9942 else => |err| {
9983 current_thread.endSyscall();9943 syscall.finish();
9984 return posix.unexpectedErrno(err);9944 return posix.unexpectedErrno(err);
9985 },9945 },
9986 }9946 }
9987 };9947 };
9988 current_thread.endSyscall();9948 syscall.finish();
9989 break fd;9949 break fd;
9990 },9950 },
9991 .INTR => {9951 .INTR => {
9992 try current_thread.checkCancel();9952 try syscall.checkCancel();
9993 continue;9953 continue;
9994 },9954 },
9995 else => |e| {9955 else => |e| {
9996 current_thread.endSyscall();9956 syscall.finish();
9997 switch (e) {9957 switch (e) {
9998 .AGAIN => |err| return errnoBug(err),9958 .AGAIN => |err| return errnoBug(err),
9999 .BADF => |err| return errnoBug(err), // File descriptor used after closed.9959 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
...@@ -10022,14 +9982,13 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve...@@ -10022,14 +9982,13 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
10022fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net.Server.AcceptError!net.Stream {9982fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net.Server.AcceptError!net.Stream {
10023 if (!have_networking) return error.NetworkDown;9983 if (!have_networking) return error.NetworkDown;
10024 const t: *Threaded = @ptrCast(@alignCast(userdata));9984 const t: *Threaded = @ptrCast(@alignCast(userdata));
10025 const current_thread = Thread.getCurrent(t);
10026 var storage: WsaAddress = undefined;9985 var storage: WsaAddress = undefined;
10027 var addr_len: i32 = @sizeOf(WsaAddress);9986 var addr_len: i32 = @sizeOf(WsaAddress);
10028 try current_thread.beginSyscall();9987 const syscall: Syscall = try .start();
10029 while (true) {9988 while (true) {
10030 const rc = ws2_32.accept(listen_handle, &storage.any, &addr_len);9989 const rc = ws2_32.accept(listen_handle, &storage.any, &addr_len);
10031 if (rc != ws2_32.INVALID_SOCKET) {9990 if (rc != ws2_32.INVALID_SOCKET) {
10032 current_thread.endSyscall();9991 syscall.finish();
10033 return .{ .socket = .{9992 return .{ .socket = .{
10034 .handle = rc,9993 .handle = rc,
10035 .address = addressFromWsa(&storage),9994 .address = addressFromWsa(&storage),
...@@ -10037,16 +9996,16 @@ fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net...@@ -10037,16 +9996,16 @@ fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net
10037 }9996 }
10038 switch (ws2_32.WSAGetLastError()) {9997 switch (ws2_32.WSAGetLastError()) {
10039 .EINTR => {9998 .EINTR => {
10040 try current_thread.checkCancel();9999 try syscall.checkCancel();
10041 continue;10000 continue;
10042 },10001 },
10043 .NOTINITIALISED => {10002 .NOTINITIALISED => {
10044 try initializeWsa(t);10003 try initializeWsa(t);
10045 try current_thread.checkCancel();10004 try syscall.checkCancel();
10046 continue;10005 continue;
10047 },10006 },
10048 else => |e| {10007 else => |e| {
10049 current_thread.endSyscall();10008 syscall.finish();
10050 switch (e) {10009 switch (e) {
10051 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,10010 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
10052 .ECONNRESET => return error.ConnectionAborted,10011 .ECONNRESET => return error.ConnectionAborted,
...@@ -10073,7 +10032,7 @@ fn netAcceptUnavailable(userdata: ?*anyopaque, listen_handle: net.Socket.Handle)...@@ -10073,7 +10032,7 @@ fn netAcceptUnavailable(userdata: ?*anyopaque, listen_handle: net.Socket.Handle)
10073fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {10032fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
10074 if (!have_networking) return error.NetworkDown;10033 if (!have_networking) return error.NetworkDown;
10075 const t: *Threaded = @ptrCast(@alignCast(userdata));10034 const t: *Threaded = @ptrCast(@alignCast(userdata));
10076 const current_thread = Thread.getCurrent(t);10035 _ = t;
1007710036
10078 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;10037 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;
10079 var i: usize = 0;10038 var i: usize = 0;
...@@ -10088,20 +10047,20 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net....@@ -10088,20 +10047,20 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
10088 assert(dest[0].len > 0);10047 assert(dest[0].len > 0);
1008910048
10090 if (native_os == .wasi and !builtin.link_libc) {10049 if (native_os == .wasi and !builtin.link_libc) {
10091 try current_thread.beginSyscall();10050 const syscall: Syscall = try .start();
10092 while (true) {10051 while (true) {
10093 var n: usize = undefined;10052 var n: usize = undefined;
10094 switch (std.os.wasi.fd_read(fd, dest.ptr, dest.len, &n)) {10053 switch (std.os.wasi.fd_read(fd, dest.ptr, dest.len, &n)) {
10095 .SUCCESS => {10054 .SUCCESS => {
10096 current_thread.endSyscall();10055 syscall.finish();
10097 return n;10056 return n;
10098 },10057 },
10099 .INTR => {10058 .INTR => {
10100 try current_thread.checkCancel();10059 try syscall.checkCancel();
10101 continue;10060 continue;
10102 },10061 },
10103 else => |e| {10062 else => |e| {
10104 current_thread.endSyscall();10063 syscall.finish();
10105 switch (e) {10064 switch (e) {
10106 .INVAL => |err| return errnoBug(err),10065 .INVAL => |err| return errnoBug(err),
10107 .FAULT => |err| return errnoBug(err),10066 .FAULT => |err| return errnoBug(err),
...@@ -10120,20 +10079,20 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net....@@ -10120,20 +10079,20 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
10120 }10079 }
10121 }10080 }
1012210081
10123 try current_thread.beginSyscall();10082 const syscall: Syscall = try .start();
10124 while (true) {10083 while (true) {
10125 const rc = posix.system.readv(fd, dest.ptr, @intCast(dest.len));10084 const rc = posix.system.readv(fd, dest.ptr, @intCast(dest.len));
10126 switch (posix.errno(rc)) {10085 switch (posix.errno(rc)) {
10127 .SUCCESS => {10086 .SUCCESS => {
10128 current_thread.endSyscall();10087 syscall.finish();
10129 return @intCast(rc);10088 return @intCast(rc);
10130 },10089 },
10131 .INTR => {10090 .INTR => {
10132 try current_thread.checkCancel();10091 try syscall.checkCancel();
10133 continue;10092 continue;
10134 },10093 },
10135 else => |e| {10094 else => |e| {
10136 current_thread.endSyscall();10095 syscall.finish();
10137 switch (e) {10096 switch (e) {
10138 .INVAL => |err| return errnoBug(err),10097 .INVAL => |err| return errnoBug(err),
10139 .FAULT => |err| return errnoBug(err),10098 .FAULT => |err| return errnoBug(err),
...@@ -10156,7 +10115,6 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net....@@ -10156,7 +10115,6 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
10156fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {10115fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
10157 if (!have_networking) return error.NetworkDown;10116 if (!have_networking) return error.NetworkDown;
10158 const t: *Threaded = @ptrCast(@alignCast(userdata));10117 const t: *Threaded = @ptrCast(@alignCast(userdata));
10159 const current_thread = Thread.getCurrent(t);
1016010118
10161 const bufs = b: {10119 const bufs = b: {
10162 var iovec_buffer: [max_iovecs_len]ws2_32.WSABUF = undefined;10120 var iovec_buffer: [max_iovecs_len]ws2_32.WSABUF = undefined;
...@@ -10184,7 +10142,7 @@ fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8...@@ -10184,7 +10142,7 @@ fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8
10184 };10142 };
1018510143
10186 while (true) {10144 while (true) {
10187 try current_thread.checkCancel();10145 try Thread.checkCancel();
1018810146
10189 var flags: u32 = 0;10147 var flags: u32 = 0;
10190 var overlapped: windows.OVERLAPPED = std.mem.zeroes(windows.OVERLAPPED);10148 var overlapped: windows.OVERLAPPED = std.mem.zeroes(windows.OVERLAPPED);
...@@ -10244,7 +10202,6 @@ fn netSendPosix(...@@ -10244,7 +10202,6 @@ fn netSendPosix(
10244) struct { ?net.Socket.SendError, usize } {10202) struct { ?net.Socket.SendError, usize } {
10245 if (!have_networking) return .{ error.NetworkDown, 0 };10203 if (!have_networking) return .{ error.NetworkDown, 0 };
10246 const t: *Threaded = @ptrCast(@alignCast(userdata));10204 const t: *Threaded = @ptrCast(@alignCast(userdata));
10247 const current_thread = Thread.getCurrent(t);
1024810205
10249 const posix_flags: u32 =10206 const posix_flags: u32 =
10250 @as(u32, if (@hasDecl(posix.MSG, "CONFIRM") and flags.confirm) posix.MSG.CONFIRM else 0) |10207 @as(u32, if (@hasDecl(posix.MSG, "CONFIRM") and flags.confirm) posix.MSG.CONFIRM else 0) |
...@@ -10257,10 +10214,10 @@ fn netSendPosix(...@@ -10257,10 +10214,10 @@ fn netSendPosix(
10257 var i: usize = 0;10214 var i: usize = 0;
10258 while (messages.len - i != 0) {10215 while (messages.len - i != 0) {
10259 if (have_sendmmsg) {10216 if (have_sendmmsg) {
10260 i += netSendMany(current_thread, handle, messages[i..], posix_flags) catch |err| return .{ err, i };10217 i += netSendMany(handle, messages[i..], posix_flags) catch |err| return .{ err, i };
10261 continue;10218 continue;
10262 }10219 }
10263 netSendOne(t, current_thread, handle, &messages[i], posix_flags) catch |err| return .{ err, i };10220 netSendOne(t, handle, &messages[i], posix_flags) catch |err| return .{ err, i };
10264 i += 1;10221 i += 1;
10265 }10222 }
10266 return .{ null, i };10223 return .{ null, i };
...@@ -10296,7 +10253,6 @@ fn netSendUnavailable(...@@ -10296,7 +10253,6 @@ fn netSendUnavailable(
1029610253
10297fn netSendOne(10254fn netSendOne(
10298 t: *Threaded,10255 t: *Threaded,
10299 current_thread: *Thread,
10300 handle: net.Socket.Handle,10256 handle: net.Socket.Handle,
10301 message: *net.OutgoingMessage,10257 message: *net.OutgoingMessage,
10302 flags: u32,10258 flags: u32,
...@@ -10313,27 +10269,27 @@ fn netSendOne(...@@ -10313,27 +10269,27 @@ fn netSendOne(
10313 .controllen = @intCast(message.control.len),10269 .controllen = @intCast(message.control.len),
10314 .flags = 0,10270 .flags = 0,
10315 };10271 };
10316 try current_thread.beginSyscall();10272 const syscall: Syscall = try .start();
10317 while (true) {10273 while (true) {
10318 const rc = posix.system.sendmsg(handle, &msg, flags);10274 const rc = posix.system.sendmsg(handle, &msg, flags);
10319 if (is_windows) {10275 if (is_windows) {
10320 if (rc != ws2_32.SOCKET_ERROR) {10276 if (rc != ws2_32.SOCKET_ERROR) {
10321 current_thread.endSyscall();10277 syscall.finish();
10322 message.data_len = @intCast(rc);10278 message.data_len = @intCast(rc);
10323 return;10279 return;
10324 }10280 }
10325 switch (ws2_32.WSAGetLastError()) {10281 switch (ws2_32.WSAGetLastError()) {
10326 .EINTR => {10282 .EINTR => {
10327 try current_thread.checkCancel();10283 try syscall.checkCancel();
10328 continue;10284 continue;
10329 },10285 },
10330 .NOTINITIALISED => {10286 .NOTINITIALISED => {
10331 try initializeWsa(t);10287 try initializeWsa(t);
10332 try current_thread.checkCancel();10288 try syscall.checkCancel();
10333 continue;10289 continue;
10334 },10290 },
10335 else => |e| {10291 else => |e| {
10336 current_thread.endSyscall();10292 syscall.finish();
10337 switch (e) {10293 switch (e) {
10338 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,10294 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
10339 .EACCES => return error.AccessDenied,10295 .EACCES => return error.AccessDenied,
...@@ -10359,16 +10315,16 @@ fn netSendOne(...@@ -10359,16 +10315,16 @@ fn netSendOne(
10359 }10315 }
10360 switch (posix.errno(rc)) {10316 switch (posix.errno(rc)) {
10361 .SUCCESS => {10317 .SUCCESS => {
10362 current_thread.endSyscall();10318 syscall.finish();
10363 message.data_len = @intCast(rc);10319 message.data_len = @intCast(rc);
10364 return;10320 return;
10365 },10321 },
10366 .INTR => {10322 .INTR => {
10367 try current_thread.checkCancel();10323 try syscall.checkCancel();
10368 continue;10324 continue;
10369 },10325 },
10370 else => |e| {10326 else => |e| {
10371 current_thread.endSyscall();10327 syscall.finish();
10372 switch (e) {10328 switch (e) {
10373 .ACCES => return error.AccessDenied,10329 .ACCES => return error.AccessDenied,
10374 .ALREADY => return error.FastOpenAlreadyInProgress,10330 .ALREADY => return error.FastOpenAlreadyInProgress,
...@@ -10397,7 +10353,6 @@ fn netSendOne(...@@ -10397,7 +10353,6 @@ fn netSendOne(
10397}10353}
1039810354
10399fn netSendMany(10355fn netSendMany(
10400 current_thread: *Thread,
10401 handle: net.Socket.Handle,10356 handle: net.Socket.Handle,
10402 messages: []net.OutgoingMessage,10357 messages: []net.OutgoingMessage,
10403 flags: u32,10358 flags: u32,
...@@ -10427,12 +10382,12 @@ fn netSendMany(...@@ -10427,12 +10382,12 @@ fn netSendMany(
10427 };10382 };
10428 }10383 }
1042910384
10430 try current_thread.beginSyscall();10385 const syscall: Syscall = try .start();
10431 while (true) {10386 while (true) {
10432 const rc = posix.system.sendmmsg(handle, clamped_msgs.ptr, @intCast(clamped_msgs.len), flags);10387 const rc = posix.system.sendmmsg(handle, clamped_msgs.ptr, @intCast(clamped_msgs.len), flags);
10433 switch (posix.errno(rc)) {10388 switch (posix.errno(rc)) {
10434 .SUCCESS => {10389 .SUCCESS => {
10435 current_thread.endSyscall();10390 syscall.finish();
10436 const n: usize = @intCast(rc);10391 const n: usize = @intCast(rc);
10437 for (clamped_messages[0..n], clamped_msgs[0..n]) |*message, *msg| {10392 for (clamped_messages[0..n], clamped_msgs[0..n]) |*message, *msg| {
10438 message.data_len = msg.len;10393 message.data_len = msg.len;
...@@ -10440,11 +10395,11 @@ fn netSendMany(...@@ -10440,11 +10395,11 @@ fn netSendMany(
10440 return n;10395 return n;
10441 },10396 },
10442 .INTR => {10397 .INTR => {
10443 try current_thread.checkCancel();10398 try syscall.checkCancel();
10444 continue;10399 continue;
10445 },10400 },
10446 else => |e| {10401 else => |e| {
10447 current_thread.endSyscall();10402 syscall.finish();
10448 switch (e) {10403 switch (e) {
10449 .AGAIN => |err| return errnoBug(err),10404 .AGAIN => |err| return errnoBug(err),
10450 .ALREADY => return error.FastOpenAlreadyInProgress,10405 .ALREADY => return error.FastOpenAlreadyInProgress,
...@@ -10482,7 +10437,6 @@ fn netReceivePosix(...@@ -10482,7 +10437,6 @@ fn netReceivePosix(
10482) struct { ?net.Socket.ReceiveTimeoutError, usize } {10437) struct { ?net.Socket.ReceiveTimeoutError, usize } {
10483 if (!have_networking) return .{ error.NetworkDown, 0 };10438 if (!have_networking) return .{ error.NetworkDown, 0 };
10484 const t: *Threaded = @ptrCast(@alignCast(userdata));10439 const t: *Threaded = @ptrCast(@alignCast(userdata));
10485 const current_thread = Thread.getCurrent(t);
10486 const t_io = io(t);10440 const t_io = io(t);
1048710441
10488 // recvmmsg is useless, here's why:10442 // recvmmsg is useless, here's why:
...@@ -10528,9 +10482,12 @@ fn netReceivePosix(...@@ -10528,9 +10482,12 @@ fn netReceivePosix(
10528 .flags = undefined,10482 .flags = undefined,
10529 };10483 };
1053010484
10531 current_thread.beginSyscall() catch |err| return .{ err, message_i };10485 const recv_rc = rc: {
10532 const recv_rc = posix.system.recvmsg(handle, &msg, posix_flags);10486 const syscall = Syscall.start() catch |err| return .{ err, message_i };
10533 current_thread.endSyscall();10487 const rc = posix.system.recvmsg(handle, &msg, posix_flags);
10488 syscall.finish();
10489 break :rc rc;
10490 };
10534 switch (posix.errno(recv_rc)) {10491 switch (posix.errno(recv_rc)) {
10535 .SUCCESS => {10492 .SUCCESS => {
10536 const data = remaining_data_buffer[0..@intCast(recv_rc)];10493 const data = remaining_data_buffer[0..@intCast(recv_rc)];
...@@ -10560,9 +10517,9 @@ fn netReceivePosix(...@@ -10560,9 +10517,9 @@ fn netReceivePosix(
10560 break :t @intCast(@min(max_poll_ms, duration.raw.toMilliseconds()));10517 break :t @intCast(@min(max_poll_ms, duration.raw.toMilliseconds()));
10561 } else max_poll_ms;10518 } else max_poll_ms;
1056210519
10563 current_thread.beginSyscall() catch |err| return .{ err, message_i };10520 const syscall = Syscall.start() catch |err| return .{ err, message_i };
10564 const poll_rc = posix.system.poll(&poll_fds, poll_fds.len, timeout_ms);10521 const poll_rc = posix.system.poll(&poll_fds, poll_fds.len, timeout_ms);
10565 current_thread.endSyscall();10522 syscall.finish();
1056610523
10567 switch (posix.errno(poll_rc)) {10524 switch (posix.errno(poll_rc)) {
10568 .SUCCESS => {10525 .SUCCESS => {
...@@ -10648,7 +10605,7 @@ fn netWritePosix(...@@ -10648,7 +10605,7 @@ fn netWritePosix(
10648) net.Stream.Writer.Error!usize {10605) net.Stream.Writer.Error!usize {
10649 if (!have_networking) return error.NetworkDown;10606 if (!have_networking) return error.NetworkDown;
10650 const t: *Threaded = @ptrCast(@alignCast(userdata));10607 const t: *Threaded = @ptrCast(@alignCast(userdata));
10651 const current_thread = Thread.getCurrent(t);10608 _ = t;
1065210609
10653 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;10610 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;
10654 var msg: posix.msghdr_const = .{10611 var msg: posix.msghdr_const = .{
...@@ -10690,20 +10647,20 @@ fn netWritePosix(...@@ -10690,20 +10647,20 @@ fn netWritePosix(
10690 };10647 };
10691 const flags = posix.MSG.NOSIGNAL;10648 const flags = posix.MSG.NOSIGNAL;
1069210649
10693 try current_thread.beginSyscall();10650 const syscall: Syscall = try .start();
10694 while (true) {10651 while (true) {
10695 const rc = posix.system.sendmsg(fd, &msg, flags);10652 const rc = posix.system.sendmsg(fd, &msg, flags);
10696 switch (posix.errno(rc)) {10653 switch (posix.errno(rc)) {
10697 .SUCCESS => {10654 .SUCCESS => {
10698 current_thread.endSyscall();10655 syscall.finish();
10699 return @intCast(rc);10656 return @intCast(rc);
10700 },10657 },
10701 .INTR => {10658 .INTR => {
10702 try current_thread.checkCancel();10659 try syscall.checkCancel();
10703 continue;10660 continue;
10704 },10661 },
10705 else => |e| {10662 else => |e| {
10706 current_thread.endSyscall();10663 syscall.finish();
10707 switch (e) {10664 switch (e) {
10708 .ACCES => |err| return errnoBug(err),10665 .ACCES => |err| return errnoBug(err),
10709 .AGAIN => |err| return errnoBug(err),10666 .AGAIN => |err| return errnoBug(err),
...@@ -10740,7 +10697,6 @@ fn netWriteWindows(...@@ -10740,7 +10697,6 @@ fn netWriteWindows(
10740 splat: usize,10697 splat: usize,
10741) net.Stream.Writer.Error!usize {10698) net.Stream.Writer.Error!usize {
10742 const t: *Threaded = @ptrCast(@alignCast(userdata));10699 const t: *Threaded = @ptrCast(@alignCast(userdata));
10743 const current_thread = Thread.getCurrent(t);
10744 comptime assert(native_os == .windows);10700 comptime assert(native_os == .windows);
1074510701
10746 var iovecs: [max_iovecs_len]ws2_32.WSABUF = undefined;10702 var iovecs: [max_iovecs_len]ws2_32.WSABUF = undefined;
...@@ -10774,7 +10730,7 @@ fn netWriteWindows(...@@ -10774,7 +10730,7 @@ fn netWriteWindows(
10774 };10730 };
1077510731
10776 while (true) {10732 while (true) {
10777 try current_thread.checkCancel();10733 try Thread.checkCancel();
1077810734
10779 var n: u32 = undefined;10735 var n: u32 = undefined;
10780 var overlapped: windows.OVERLAPPED = std.mem.zeroes(windows.OVERLAPPED);10736 var overlapped: windows.OVERLAPPED = std.mem.zeroes(windows.OVERLAPPED);
...@@ -10884,7 +10840,7 @@ fn netCloseUnavailable(userdata: ?*anyopaque, handles: []const net.Socket.Handle...@@ -10884,7 +10840,7 @@ fn netCloseUnavailable(userdata: ?*anyopaque, handles: []const net.Socket.Handle
10884fn netShutdownPosix(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void {10840fn netShutdownPosix(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void {
10885 if (!have_networking) return error.NetworkDown;10841 if (!have_networking) return error.NetworkDown;
10886 const t: *Threaded = @ptrCast(@alignCast(userdata));10842 const t: *Threaded = @ptrCast(@alignCast(userdata));
10887 const current_thread = Thread.getCurrent(t);10843 _ = t;
1088810844
10889 const posix_how: i32 = switch (how) {10845 const posix_how: i32 = switch (how) {
10890 .recv => posix.SHUT.RD,10846 .recv => posix.SHUT.RD,
...@@ -10892,19 +10848,16 @@ fn netShutdownPosix(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.S...@@ -10892,19 +10848,16 @@ fn netShutdownPosix(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.S
10892 .both => posix.SHUT.RDWR,10848 .both => posix.SHUT.RDWR,
10893 };10849 };
1089410850
10895 try current_thread.beginSyscall();10851 const syscall: Syscall = try .start();
10896 while (true) {10852 while (true) {
10897 switch (posix.errno(posix.system.shutdown(handle, posix_how))) {10853 switch (posix.errno(posix.system.shutdown(handle, posix_how))) {
10898 .SUCCESS => {10854 .SUCCESS => return syscall.finish(),
10899 current_thread.endSyscall();
10900 return;
10901 },
10902 .INTR => {10855 .INTR => {
10903 try current_thread.checkCancel();10856 try syscall.checkCancel();
10904 continue;10857 continue;
10905 },10858 },
10906 else => |e| {10859 else => |e| {
10907 current_thread.endSyscall();10860 syscall.finish();
10908 switch (e) {10861 switch (e) {
10909 .BADF, .NOTSOCK, .INVAL => |err| return errnoBug(err),10862 .BADF, .NOTSOCK, .INVAL => |err| return errnoBug(err),
10910 .NOTCONN => return error.SocketUnconnected,10863 .NOTCONN => return error.SocketUnconnected,
...@@ -10970,10 +10923,10 @@ fn netInterfaceNameResolve(...@@ -10970,10 +10923,10 @@ fn netInterfaceNameResolve(
10970) net.Interface.Name.ResolveError!net.Interface {10923) net.Interface.Name.ResolveError!net.Interface {
10971 if (!have_networking) return error.InterfaceNotFound;10924 if (!have_networking) return error.InterfaceNotFound;
10972 const t: *Threaded = @ptrCast(@alignCast(userdata));10925 const t: *Threaded = @ptrCast(@alignCast(userdata));
10973 const current_thread = Thread.getCurrent(t);10926 _ = t;
1097410927
10975 if (native_os == .linux) {10928 if (native_os == .linux) {
10976 const sock_fd = openSocketPosix(current_thread, posix.AF.UNIX, .{ .mode = .dgram }) catch |err| switch (err) {10929 const sock_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .dgram }) catch |err| switch (err) {
10977 error.ProcessFdQuotaExceeded => return error.SystemResources,10930 error.ProcessFdQuotaExceeded => return error.SystemResources,
10978 error.SystemFdQuotaExceeded => return error.SystemResources,10931 error.SystemFdQuotaExceeded => return error.SystemResources,
10979 error.AddressFamilyUnsupported => return error.Unexpected,10932 error.AddressFamilyUnsupported => return error.Unexpected,
...@@ -10990,19 +10943,19 @@ fn netInterfaceNameResolve(...@@ -10990,19 +10943,19 @@ fn netInterfaceNameResolve(
10990 .ifru = undefined,10943 .ifru = undefined,
10991 };10944 };
1099210945
10993 try current_thread.beginSyscall();10946 const syscall: Syscall = try .start();
10994 while (true) {10947 while (true) {
10995 switch (posix.errno(posix.system.ioctl(sock_fd, posix.SIOCGIFINDEX, @intFromPtr(&ifr)))) {10948 switch (posix.errno(posix.system.ioctl(sock_fd, posix.SIOCGIFINDEX, @intFromPtr(&ifr)))) {
10996 .SUCCESS => {10949 .SUCCESS => {
10997 current_thread.endSyscall();10950 syscall.finish();
10998 return .{ .index = @bitCast(ifr.ifru.ivalue) };10951 return .{ .index = @bitCast(ifr.ifru.ivalue) };
10999 },10952 },
11000 .INTR => {10953 .INTR => {
11001 try current_thread.checkCancel();10954 try syscall.checkCancel();
11002 continue;10955 continue;
11003 },10956 },
11004 else => |e| {10957 else => |e| {
11005 current_thread.endSyscall();10958 syscall.finish();
11006 switch (e) {10959 switch (e) {
11007 .INVAL => |err| return errnoBug(err), // Bad parameters.10960 .INVAL => |err| return errnoBug(err), // Bad parameters.
11008 .NOTTY => |err| return errnoBug(err),10961 .NOTTY => |err| return errnoBug(err),
...@@ -11019,12 +10972,12 @@ fn netInterfaceNameResolve(...@@ -11019,12 +10972,12 @@ fn netInterfaceNameResolve(
11019 }10972 }
1102010973
11021 if (native_os == .windows) {10974 if (native_os == .windows) {
11022 try current_thread.checkCancel();10975 try Thread.checkCancel();
11023 @panic("TODO implement netInterfaceNameResolve for Windows");10976 @panic("TODO implement netInterfaceNameResolve for Windows");
11024 }10977 }
1102510978
11026 if (builtin.link_libc) {10979 if (builtin.link_libc) {
11027 try current_thread.checkCancel();10980 try Thread.checkCancel();
11028 const index = std.c.if_nametoindex(&name.bytes);10981 const index = std.c.if_nametoindex(&name.bytes);
11029 if (index == 0) return error.InterfaceNotFound;10982 if (index == 0) return error.InterfaceNotFound;
11030 return .{ .index = @bitCast(index) };10983 return .{ .index = @bitCast(index) };
...@@ -11044,8 +10997,8 @@ fn netInterfaceNameResolveUnavailable(...@@ -11044,8 +10997,8 @@ fn netInterfaceNameResolveUnavailable(
1104410997
11045fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {10998fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {
11046 const t: *Threaded = @ptrCast(@alignCast(userdata));10999 const t: *Threaded = @ptrCast(@alignCast(userdata));
11047 const current_thread = Thread.getCurrent(t);11000 _ = t;
11048 try current_thread.checkCancel();11001 try Thread.checkCancel();
1104911002
11050 if (native_os == .linux) {11003 if (native_os == .linux) {
11051 _ = interface;11004 _ = interface;
...@@ -11104,7 +11057,6 @@ fn netLookupFallible(...@@ -11104,7 +11057,6 @@ fn netLookupFallible(
11104) (net.HostName.LookupError || Io.QueueClosedError)!void {11057) (net.HostName.LookupError || Io.QueueClosedError)!void {
11105 if (!have_networking) return error.NetworkDown;11058 if (!have_networking) return error.NetworkDown;
1110611059
11107 const current_thread: *Thread = .getCurrent(t);
11108 const t_io = io(t);11060 const t_io = io(t);
11109 const name = host_name.bytes;11061 const name = host_name.bytes;
11110 assert(name.len <= HostName.max_len);11062 assert(name.len <= HostName.max_len);
...@@ -11145,7 +11097,7 @@ fn netLookupFallible(...@@ -11145,7 +11097,7 @@ fn netLookupFallible(
11145 var res: *ws2_32.ADDRINFOEXW = undefined;11097 var res: *ws2_32.ADDRINFOEXW = undefined;
11146 const timeout: ?*ws2_32.timeval = null;11098 const timeout: ?*ws2_32.timeval = null;
11147 while (true) {11099 while (true) {
11148 try current_thread.checkCancel(); // TODO make requestCancel call GetAddrInfoExCancel11100 try Thread.checkCancel();
11149 // TODO make this append to the queue eagerly rather than blocking until11101 // TODO make this append to the queue eagerly rather than blocking until
11150 // the whole thing finishes11102 // the whole thing finishes
11151 const rc: ws2_32.WinsockError = @enumFromInt(ws2_32.GetAddrInfoExW(name_w, port_w, .DNS, null, &hints, &res, timeout, null, null, cancel_handle));11103 const rc: ws2_32.WinsockError = @enumFromInt(ws2_32.GetAddrInfoExW(name_w, port_w, .DNS, null, &hints, &res, timeout, null, null, cancel_handle));
...@@ -11292,25 +11244,25 @@ fn netLookupFallible(...@@ -11292,25 +11244,25 @@ fn netLookupFallible(
11292 .next = null,11244 .next = null,
11293 };11245 };
11294 var res: ?*posix.addrinfo = null;11246 var res: ?*posix.addrinfo = null;
11295 try current_thread.beginSyscall();11247 const syscall: Syscall = try .start();
11296 while (true) {11248 while (true) {
11297 switch (posix.system.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res)) {11249 switch (posix.system.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res)) {
11298 @as(posix.system.EAI, @enumFromInt(0)) => {11250 @as(posix.system.EAI, @enumFromInt(0)) => {
11299 current_thread.endSyscall();11251 syscall.finish();
11300 break;11252 break;
11301 },11253 },
11302 .SYSTEM => switch (posix.errno(-1)) {11254 .SYSTEM => switch (posix.errno(-1)) {
11303 .INTR => {11255 .INTR => {
11304 try current_thread.checkCancel();11256 try syscall.checkCancel();
11305 continue;11257 continue;
11306 },11258 },
11307 else => |e| {11259 else => |e| {
11308 current_thread.endSyscall();11260 syscall.finish();
11309 return posix.unexpectedErrno(e);11261 return posix.unexpectedErrno(e);
11310 },11262 },
11311 },11263 },
11312 else => |e| {11264 else => |e| {
11313 current_thread.endSyscall();11265 syscall.finish();
11314 switch (e) {11266 switch (e) {
11315 .ADDRFAMILY => return error.AddressFamilyUnsupported,11267 .ADDRFAMILY => return error.AddressFamilyUnsupported,
11316 .AGAIN => return error.NameServerFailure,11268 .AGAIN => return error.NameServerFailure,
...@@ -11397,15 +11349,15 @@ fn unlockStderr(userdata: ?*anyopaque) void {...@@ -11397,15 +11349,15 @@ fn unlockStderr(userdata: ?*anyopaque) void {
11397fn processSetCurrentDir(userdata: ?*anyopaque, dir: Dir) std.process.SetCurrentDirError!void {11349fn processSetCurrentDir(userdata: ?*anyopaque, dir: Dir) std.process.SetCurrentDirError!void {
11398 if (native_os == .wasi) return error.OperationUnsupported;11350 if (native_os == .wasi) return error.OperationUnsupported;
11399 const t: *Threaded = @ptrCast(@alignCast(userdata));11351 const t: *Threaded = @ptrCast(@alignCast(userdata));
11400 const current_thread = Thread.getCurrent(t);11352 _ = t;
1140111353
11402 if (is_windows) {11354 if (is_windows) {
11403 try current_thread.checkCancel();11355 try Thread.checkCancel();
11404 var dir_path_buffer: [windows.PATH_MAX_WIDE]u16 = undefined;11356 var dir_path_buffer: [windows.PATH_MAX_WIDE]u16 = undefined;
11405 // TODO move GetFinalPathNameByHandle logic into std.Io.Threaded and add cancel checks11357 // TODO move GetFinalPathNameByHandle logic into std.Io.Threaded and add cancel checks
11406 const dir_path = try windows.GetFinalPathNameByHandle(dir.handle, .{}, &dir_path_buffer);11358 const dir_path = try windows.GetFinalPathNameByHandle(dir.handle, .{}, &dir_path_buffer);
11407 const path_len_bytes = std.math.cast(u16, dir_path.len * 2) orelse return error.NameTooLong;11359 const path_len_bytes = std.math.cast(u16, dir_path.len * 2) orelse return error.NameTooLong;
11408 try current_thread.checkCancel();11360 try Thread.checkCancel();
11409 var nt_name: windows.UNICODE_STRING = .{11361 var nt_name: windows.UNICODE_STRING = .{
11410 .Length = path_len_bytes,11362 .Length = path_len_bytes,
11411 .MaximumLength = path_len_bytes,11363 .MaximumLength = path_len_bytes,
...@@ -11427,32 +11379,32 @@ fn processSetCurrentDir(userdata: ?*anyopaque, dir: Dir) std.process.SetCurrentD...@@ -11427,32 +11379,32 @@ fn processSetCurrentDir(userdata: ?*anyopaque, dir: Dir) std.process.SetCurrentD
1142711379
11428 if (dir.handle == posix.AT.FDCWD) return;11380 if (dir.handle == posix.AT.FDCWD) return;
1142911381
11430 try current_thread.beginSyscall();11382 const syscall: Syscall = try .start();
11431 while (true) {11383 while (true) {
11432 switch (posix.errno(posix.system.fchdir(dir.handle))) {11384 switch (posix.errno(posix.system.fchdir(dir.handle))) {
11433 .SUCCESS => return current_thread.endSyscall(),11385 .SUCCESS => return syscall.finish(),
11434 .INTR => {11386 .INTR => {
11435 try current_thread.checkCancel();11387 try syscall.checkCancel();
11436 continue;11388 continue;
11437 },11389 },
11438 .ACCES => {11390 .ACCES => {
11439 current_thread.endSyscall();11391 syscall.finish();
11440 return error.AccessDenied;11392 return error.AccessDenied;
11441 },11393 },
11442 .BADF => |err| {11394 .BADF => |err| {
11443 current_thread.endSyscall();11395 syscall.finish();
11444 return errnoBug(err);11396 return errnoBug(err);
11445 },11397 },
11446 .NOTDIR => {11398 .NOTDIR => {
11447 current_thread.endSyscall();11399 syscall.finish();
11448 return error.NotDir;11400 return error.NotDir;
11449 },11401 },
11450 .IO => {11402 .IO => {
11451 current_thread.endSyscall();11403 syscall.finish();
11452 return error.FileSystem;11404 return error.FileSystem;
11453 },11405 },
11454 else => |err| {11406 else => |err| {
11455 current_thread.endSyscall();11407 syscall.finish();
11456 return posix.unexpectedErrno(err);11408 return posix.unexpectedErrno(err);
11457 },11409 },
11458 }11410 }