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 {
321321 var timeout_ns: u64 = 1 << 10;
322322 while (true) {
323323 need_signal = need_signal and g.signalAllCanceledSyscalls(t) and t.robust_cancel == .enabled;
324 Thread.futexWaitTimed(
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 };
324 Thread.futexWaitUncancelable(&num_completed.raw, 0, if (need_signal) timeout_ns else null);
332325 switch (num_completed.load(.acquire)) { // acquire task results
333326 0 => {},
334327 1 => break,
......@@ -482,14 +475,7 @@ const Future = struct {
482475 var timeout_ns: u64 = 1 << 10;
483476 while (true) {
484477 need_signal = need_signal and thread.?.signalCanceledSyscall(t, .fromFuture(future)) and t.robust_cancel == .enabled;
485 Thread.futexWaitTimed(
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 };
478 Thread.futexWaitUncancelable(&num_completed.raw, 0, if (need_signal) timeout_ns else null);
493479 switch (num_completed.load(.acquire)) { // acquire task results
494480 0 => {},
495481 1 => break,
......@@ -615,22 +601,22 @@ const Thread = struct {
615601 return if (std.Thread.use_pthreads) std.c.pthread_self() else std.Thread.getCurrentId();
616602 }
617603
618 fn futexWaitUncancelable(ptr: *const u32, expect: u32) void {
619 return Thread.futexWaitTimed(null, ptr, expect, null) catch unreachable;
604 fn futexWaitUncancelable(ptr: *const u32, expect: u32, timeout_ns: ?u64) void {
605 return Thread.futexWaitInner(ptr, expect, true, timeout_ns) catch unreachable;
620606 }
621607
622 fn futexWait(thread: *Thread, ptr: *const u32, expect: u32) Io.Cancelable!void {
623 return Thread.futexWaitTimed(thread, ptr, expect, null);
608 fn futexWait(ptr: *const u32, expect: u32, timeout_ns: ?u64) Io.Cancelable!void {
609 return Thread.futexWaitInner(ptr, expect, false, timeout_ns);
624610 }
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 {
627613 @branchHint(.cold);
628614
629615 if (builtin.single_threaded) unreachable; // nobody would ever wake us
630616
631617 if (builtin.cpu.arch.isWasm()) {
632618 comptime assert(builtin.cpu.has(.wasm, .atomics));
633 if (thread) |t| try t.checkCancel();
619 if (!uncancelable) try Thread.checkCancel();
634620 const to: i64 = if (timeout_ns) |ns| ns else -1;
635621 const signed_expect: i32 = @bitCast(expect);
636622 const result = asm volatile (
......@@ -658,9 +644,9 @@ const Thread = struct {
658644 ts_buffer = timestampToPosix(ns);
659645 break :ts &ts_buffer;
660646 } else null;
661 if (thread) |t| try t.beginSyscall();
647 const syscall: Syscall = if (uncancelable) .{ .thread = null } else try .start();
662648 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, ts);
663 if (thread) |t| t.endSyscall();
649 syscall.finish();
664650 switch (linux.errno(rc)) {
665651 .SUCCESS => {}, // notified by `wake()`
666652 .INTR => {}, // caller's responsibility to retry
......@@ -677,7 +663,7 @@ const Thread = struct {
677663 .op = .COMPARE_AND_WAIT,
678664 .NO_ERRNO = true,
679665 };
680 if (thread) |t| try t.beginSyscall();
666 const syscall: Syscall = if (uncancelable) .{ .thread = null } else try .start();
681667 const status = switch (darwin_supports_ulock_wait2) {
682668 true => c.__ulock_wait2(flags, ptr, expect, ns: {
683669 const ns = timeout_ns orelse break :ns 0;
......@@ -691,7 +677,7 @@ const Thread = struct {
691677 break :us us;
692678 }),
693679 };
694 if (thread) |t| t.endSyscall();
680 syscall.finish();
695681 if (status >= 0) return;
696682 switch (@as(c.E, @enumFromInt(-status))) {
697683 .INTR => {}, // spurious wake
......@@ -713,7 +699,7 @@ const Thread = struct {
713699 timeout_value = -timeout_value;
714700 timeout_ptr = &timeout_value;
715701 }
716 if (thread) |t| try t.checkCancel();
702 if (!uncancelable) try Thread.checkCancel();
717703 switch (windows.ntdll.RtlWaitOnAddress(ptr, &expect, @sizeOf(@TypeOf(expect)), timeout_ptr)) {
718704 .SUCCESS => {},
719705 .CANCELLED => {},
......@@ -733,9 +719,9 @@ const Thread = struct {
733719 tm.clockid = .MONOTONIC;
734720 tm.timeout = timestampToPosix(ns);
735721 }
736 if (thread) |t| try t.beginSyscall();
722 const syscall: Syscall = if (uncancelable) .{ .thread = null } else try .start();
737723 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();
739725 if (is_debug) switch (posix.errno(rc)) {
740726 .SUCCESS => {},
741727 .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
18211807 _ = initial_token; // we need to load `token` *after* the group finishes
18221808 const t: *Threaded = @ptrCast(@alignCast(userdata));
18231809 const g: Group = .{ .ptr = type_erased };
1824 const thread: *Thread = .getCurrent(t);
18251810
18261811 var num_completed: std.atomic.Value(u32) = .init(0);
18271812 g.awaiter().* = &num_completed;
......@@ -1841,7 +1826,7 @@ fn groupAwait(userdata: ?*anyopaque, type_erased: *Io.Group, initial_token: *any
18411826 return;
18421827 }
18431828
1844 while (thread.futexWait(&num_completed.raw, 0)) {
1829 while (Thread.futexWait(&num_completed.raw, 0, null)) {
18451830 switch (num_completed.load(.acquire)) { // acquire task results
18461831 0 => continue,
18471832 1 => break,
......@@ -1907,8 +1892,9 @@ fn groupCancel(userdata: ?*anyopaque, type_erased: *Io.Group, initial_token: *an
19071892
19081893fn recancel(userdata: ?*anyopaque) void {
19091894 const t: *Threaded = @ptrCast(@alignCast(userdata));
1910 const current_thread: *Thread = .getCurrent(t);
1911 switch (current_thread.status.fetchXor(.{
1895 _ = t;
1896 const thread = Thread.current.?; // called `recancel` but was not canceled
1897 switch (thread.status.fetchXor(.{
19121898 .cancelation = @enumFromInt(0b001),
19131899 .awaitable = .null,
19141900 }, .monotonic).cancelation) {
......@@ -1924,9 +1910,10 @@ fn recancel(userdata: ?*anyopaque) void {
19241910
19251911fn swapCancelProtection(userdata: ?*anyopaque, new: Io.CancelProtection) Io.CancelProtection {
19261912 const t: *Threaded = @ptrCast(@alignCast(userdata));
1927 const current_thread: *Thread = .getCurrent(t);
1928 const old = current_thread.cancel_protection;
1929 current_thread.cancel_protection = new;
1913 _ = t;
1914 const thread = Thread.current orelse return .unblocked;
1915 const old = thread.cancel_protection;
1916 thread.cancel_protection = new;
19301917 return old;
19311918}
19321919
......@@ -1945,7 +1932,6 @@ fn await(
19451932 _ = result_alignment;
19461933 const t: *Threaded = @ptrCast(@alignCast(userdata));
19471934 const future: *Future = @ptrCast(@alignCast(any_future));
1948 const thread: *Thread = .getCurrent(t);
19491935
19501936 var num_completed: std.atomic.Value(u32) = .init(0);
19511937 future.awaiter = &num_completed;
......@@ -1955,7 +1941,7 @@ fn await(
19551941 .thread = .null,
19561942 }, .acq_rel); // acquire results if complete; release `future.awaiter`
19571943 switch (pre_await_status.tag) {
1958 .pending => while (thread.futexWait(&num_completed.raw, 0)) {
1944 .pending => while (Thread.futexWait(&num_completed.raw, 0, null)) {
19591945 switch (num_completed.load(.acquire)) { // acquire task results
19601946 0 => continue,
19611947 1 => break,
......@@ -2024,20 +2010,19 @@ fn cancel(
20242010fn futexWait(userdata: ?*anyopaque, ptr: *const u32, expected: u32, timeout: Io.Timeout) Io.Cancelable!void {
20252011 if (builtin.single_threaded) unreachable; // Deadlock.
20262012 const t: *Threaded = @ptrCast(@alignCast(userdata));
2027 const current_thread = Thread.getCurrent(t);
20282013 const t_io = ioBasic(t);
20292014 const timeout_ns: ?u64 = ns: {
20302015 const d = (timeout.toDurationFromNow(t_io) catch break :ns 10) orelse break :ns null;
20312016 break :ns std.math.lossyCast(u64, d.raw.toNanoseconds());
20322017 };
2033 return Thread.futexWaitTimed(current_thread, ptr, expected, timeout_ns);
2018 return Thread.futexWait(ptr, expected, timeout_ns);
20342019}
20352020
20362021fn futexWaitUncancelable(userdata: ?*anyopaque, ptr: *const u32, expected: u32) void {
20372022 if (builtin.single_threaded) unreachable; // Deadlock.
20382023 const t: *Threaded = @ptrCast(@alignCast(userdata));
20392024 _ = t;
2040 Thread.futexWaitUncancelable(ptr, expected);
2025 Thread.futexWaitUncancelable(ptr, expected, null);
20412026}
20422027
20432028fn futexWake(userdata: ?*anyopaque, ptr: *const u32, max_waiters: u32) void {
......@@ -2055,24 +2040,24 @@ const dirCreateDir = switch (native_os) {
20552040
20562041fn dirCreateDirPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void {
20572042 const t: *Threaded = @ptrCast(@alignCast(userdata));
2058 const current_thread = Thread.getCurrent(t);
2043 _ = t;
20592044
20602045 var path_buffer: [posix.PATH_MAX]u8 = undefined;
20612046 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
20622047
2063 try current_thread.beginSyscall();
2048 const syscall: Syscall = try .start();
20642049 while (true) {
20652050 switch (posix.errno(posix.system.mkdirat(dir.handle, sub_path_posix, permissions.toMode()))) {
20662051 .SUCCESS => {
2067 current_thread.endSyscall();
2052 syscall.finish();
20682053 return;
20692054 },
20702055 .INTR => {
2071 try current_thread.checkCancel();
2056 try syscall.checkCancel();
20722057 continue;
20732058 },
20742059 else => |e| {
2075 current_thread.endSyscall();
2060 syscall.finish();
20762061 switch (e) {
20772062 .ACCES => return error.AccessDenied,
20782063 .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
21012086fn dirCreateDirWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void {
21022087 if (builtin.link_libc) return dirCreateDirPosix(userdata, dir, sub_path, permissions);
21032088 const t: *Threaded = @ptrCast(@alignCast(userdata));
2104 const current_thread = Thread.getCurrent(t);
2105 try current_thread.beginSyscall();
2089 _ = t;
2090 const syscall: Syscall = try .start();
21062091 while (true) {
21072092 switch (std.os.wasi.path_create_directory(dir.handle, sub_path.ptr, sub_path.len)) {
21082093 .SUCCESS => {
2109 current_thread.endSyscall();
2094 syscall.finish();
21102095 return;
21112096 },
21122097 .INTR => {
2113 try current_thread.checkCancel();
2098 try syscall.checkCancel();
21142099 continue;
21152100 },
21162101 else => |e| {
2117 current_thread.endSyscall();
2102 syscall.finish();
21182103 switch (e) {
21192104 .ACCES => return error.AccessDenied,
21202105 .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
21412126
21422127fn dirCreateDirWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.CreateDirError!void {
21432128 const t: *Threaded = @ptrCast(@alignCast(userdata));
2144 const current_thread = Thread.getCurrent(t);
2145 try current_thread.checkCancel();
2129 _ = t;
2130 try Thread.checkCancel();
21462131
21472132 const sub_path_w = try windows.sliceToPrefixedFileW(dir.handle, sub_path);
21482133 _ = permissions; // TODO use this value
......@@ -2229,7 +2214,6 @@ fn dirCreateDirPathOpenWindows(
22292214 options: Dir.OpenOptions,
22302215) Dir.CreateDirPathOpenError!Dir {
22312216 const t: *Threaded = @ptrCast(@alignCast(userdata));
2232 const current_thread = Thread.getCurrent(t);
22332217 const w = windows;
22342218
22352219 _ = permissions; // TODO apply these permissions
......@@ -2242,7 +2226,7 @@ fn dirCreateDirPathOpenWindows(
22422226 };
22432227
22442228 while (true) {
2245 try current_thread.checkCancel();
2229 try Thread.checkCancel();
22462230
22472231 const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, component.path);
22482232 const sub_path_w = sub_path_w_array.span();
......@@ -2371,7 +2355,7 @@ fn dirStatFileLinux(
23712355 options: Dir.StatFileOptions,
23722356) Dir.StatFileError!File.Stat {
23732357 const t: *Threaded = @ptrCast(@alignCast(userdata));
2374 const current_thread = Thread.getCurrent(t);
2358 _ = t;
23752359 const linux = std.os.linux;
23762360 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid())
23772361 .{ .major = 30, .minor = 0, .patch = 0 }
......@@ -2385,20 +2369,20 @@ fn dirStatFileLinux(
23852369 const flags: u32 = linux.AT.NO_AUTOMOUNT |
23862370 @as(u32, if (!options.follow_symlinks) linux.AT.SYMLINK_NOFOLLOW else 0);
23872371
2388 try current_thread.beginSyscall();
2372 const syscall: Syscall = try .start();
23892373 while (true) {
23902374 var statx = std.mem.zeroes(linux.Statx);
23912375 switch (sys.errno(sys.statx(dir.handle, sub_path_posix, flags, linux_statx_request, &statx))) {
23922376 .SUCCESS => {
2393 current_thread.endSyscall();
2377 syscall.finish();
23942378 return statFromLinux(&statx);
23952379 },
23962380 .INTR => {
2397 try current_thread.checkCancel();
2381 try syscall.checkCancel();
23982382 continue;
23992383 },
24002384 else => |e| {
2401 current_thread.endSyscall();
2385 syscall.finish();
24022386 switch (e) {
24032387 .ACCES => return error.AccessDenied,
24042388 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
......@@ -2423,31 +2407,31 @@ fn dirStatFilePosix(
24232407 options: Dir.StatFileOptions,
24242408) Dir.StatFileError!File.Stat {
24252409 const t: *Threaded = @ptrCast(@alignCast(userdata));
2426 const current_thread = Thread.getCurrent(t);
2410 _ = t;
24272411
24282412 var path_buffer: [posix.PATH_MAX]u8 = undefined;
24292413 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
24302414
24312415 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);
24342418}
24352419
2436fn posixStatFile(current_thread: *Thread, dir_fd: posix.fd_t, sub_path: [:0]const u8, flags: u32) Dir.StatFileError!File.Stat {
2437 try current_thread.beginSyscall();
2420fn posixStatFile(dir_fd: posix.fd_t, sub_path: [:0]const u8, flags: u32) Dir.StatFileError!File.Stat {
2421 const syscall: Syscall = try .start();
24382422 while (true) {
24392423 var stat = std.mem.zeroes(posix.Stat);
24402424 switch (posix.errno(fstatat_sym(dir_fd, sub_path, &stat, flags))) {
24412425 .SUCCESS => {
2442 current_thread.endSyscall();
2426 syscall.finish();
24432427 return statFromPosix(&stat);
24442428 },
24452429 .INTR => {
2446 try current_thread.checkCancel();
2430 try syscall.checkCancel();
24472431 continue;
24482432 },
24492433 else => |e| {
2450 current_thread.endSyscall();
2434 syscall.finish();
24512435 switch (e) {
24522436 .INVAL => |err| return errnoBug(err),
24532437 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
......@@ -2489,25 +2473,25 @@ fn dirStatFileWasi(
24892473) Dir.StatFileError!File.Stat {
24902474 if (builtin.link_libc) return dirStatFilePosix(userdata, dir, sub_path, options);
24912475 const t: *Threaded = @ptrCast(@alignCast(userdata));
2492 const current_thread = Thread.getCurrent(t);
2476 _ = t;
24932477 const wasi = std.os.wasi;
24942478 const flags: wasi.lookupflags_t = .{
24952479 .SYMLINK_FOLLOW = options.follow_symlinks,
24962480 };
24972481 var stat: wasi.filestat_t = undefined;
2498 try current_thread.beginSyscall();
2482 const syscall: Syscall = try .start();
24992483 while (true) {
25002484 switch (wasi.path_filestat_get(dir.handle, flags, sub_path.ptr, sub_path.len, &stat)) {
25012485 .SUCCESS => {
2502 current_thread.endSyscall();
2486 syscall.finish();
25032487 return statFromWasi(&stat);
25042488 },
25052489 .INTR => {
2506 try current_thread.checkCancel();
2490 try syscall.checkCancel();
25072491 continue;
25082492 },
25092493 else => |e| {
2510 current_thread.endSyscall();
2494 syscall.finish();
25112495 switch (e) {
25122496 .INVAL => |err| return errnoBug(err),
25132497 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
......@@ -2530,24 +2514,23 @@ fn fileLength(userdata: ?*anyopaque, file: File) File.LengthError!u64 {
25302514 const t: *Threaded = @ptrCast(@alignCast(userdata));
25312515
25322516 if (native_os == .linux) {
2533 const current_thread = Thread.getCurrent(t);
25342517 const linux = std.os.linux;
25352518
2536 try current_thread.beginSyscall();
2519 const syscall: Syscall = try .start();
25372520 while (true) {
25382521 var statx = std.mem.zeroes(linux.Statx);
25392522 switch (linux.errno(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, .{ .SIZE = true }, &statx))) {
25402523 .SUCCESS => {
2541 current_thread.endSyscall();
2524 syscall.finish();
25422525 if (!statx.mask.SIZE) return error.Unexpected;
25432526 return statx.size;
25442527 },
25452528 .INTR => {
2546 try current_thread.checkCancel();
2529 try syscall.checkCancel();
25472530 continue;
25482531 },
25492532 else => |e| {
2550 current_thread.endSyscall();
2533 syscall.finish();
25512534 switch (e) {
25522535 .ACCES => |err| return errnoBug(err),
25532536 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
......@@ -2580,24 +2563,24 @@ const fileStat = switch (native_os) {
25802563
25812564fn fileStatPosix(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
25822565 const t: *Threaded = @ptrCast(@alignCast(userdata));
2583 const current_thread = Thread.getCurrent(t);
2566 _ = t;
25842567
25852568 if (posix.Stat == void) return error.Streaming;
25862569
2587 try current_thread.beginSyscall();
2570 const syscall: Syscall = try .start();
25882571 while (true) {
25892572 var stat = std.mem.zeroes(posix.Stat);
25902573 switch (posix.errno(fstat_sym(file.handle, &stat))) {
25912574 .SUCCESS => {
2592 current_thread.endSyscall();
2575 syscall.finish();
25932576 return statFromPosix(&stat);
25942577 },
25952578 .INTR => {
2596 try current_thread.checkCancel();
2579 try syscall.checkCancel();
25972580 continue;
25982581 },
25992582 else => |e| {
2600 current_thread.endSyscall();
2583 syscall.finish();
26012584 switch (e) {
26022585 .INVAL => |err| return errnoBug(err),
26032586 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
......@@ -2612,7 +2595,7 @@ fn fileStatPosix(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
26122595
26132596fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
26142597 const t: *Threaded = @ptrCast(@alignCast(userdata));
2615 const current_thread = Thread.getCurrent(t);
2598 _ = t;
26162599 const linux = std.os.linux;
26172600 const use_c = std.c.versionCheck(if (builtin.abi.isAndroid())
26182601 .{ .major = 30, .minor = 0, .patch = 0 }
......@@ -2620,20 +2603,20 @@ fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
26202603 .{ .major = 2, .minor = 28, .patch = 0 });
26212604 const sys = if (use_c) std.c else std.os.linux;
26222605
2623 try current_thread.beginSyscall();
2606 const syscall: Syscall = try .start();
26242607 while (true) {
26252608 var statx = std.mem.zeroes(linux.Statx);
26262609 switch (sys.errno(sys.statx(file.handle, "", linux.AT.EMPTY_PATH, linux_statx_request, &statx))) {
26272610 .SUCCESS => {
2628 current_thread.endSyscall();
2611 syscall.finish();
26292612 return statFromLinux(&statx);
26302613 },
26312614 .INTR => {
2632 try current_thread.checkCancel();
2615 try syscall.checkCancel();
26332616 continue;
26342617 },
26352618 else => |e| {
2636 current_thread.endSyscall();
2619 syscall.finish();
26372620 switch (e) {
26382621 .ACCES => |err| return errnoBug(err),
26392622 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
......@@ -2653,8 +2636,8 @@ fn fileStatLinux(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
26532636
26542637fn fileStatWindows(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
26552638 const t: *Threaded = @ptrCast(@alignCast(userdata));
2656 const current_thread = Thread.getCurrent(t);
2657 try current_thread.checkCancel();
2639 _ = t;
2640 try Thread.checkCancel();
26582641
26592642 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
26602643 var info: windows.FILE.ALL_INFORMATION = undefined;
......@@ -2702,22 +2685,22 @@ fn fileStatWasi(userdata: ?*anyopaque, file: File) File.StatError!File.Stat {
27022685 if (builtin.link_libc) return fileStatPosix(userdata, file);
27032686
27042687 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();
27082691 while (true) {
27092692 var stat: std.os.wasi.filestat_t = undefined;
27102693 switch (std.os.wasi.fd_filestat_get(file.handle, &stat)) {
27112694 .SUCCESS => {
2712 current_thread.endSyscall();
2695 syscall.finish();
27132696 return statFromWasi(&stat);
27142697 },
27152698 .INTR => {
2716 try current_thread.checkCancel();
2699 try syscall.checkCancel();
27172700 continue;
27182701 },
27192702 else => |e| {
2720 current_thread.endSyscall();
2703 syscall.finish();
27212704 switch (e) {
27222705 .INVAL => |err| return errnoBug(err),
27232706 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
......@@ -2744,7 +2727,7 @@ fn dirAccessPosix(
27442727 options: Dir.AccessOptions,
27452728) Dir.AccessError!void {
27462729 const t: *Threaded = @ptrCast(@alignCast(userdata));
2747 const current_thread = Thread.getCurrent(t);
2730 _ = t;
27482731
27492732 var path_buffer: [posix.PATH_MAX]u8 = undefined;
27502733 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
......@@ -2756,19 +2739,19 @@ fn dirAccessPosix(
27562739 @as(u32, if (options.write) posix.W_OK else 0) |
27572740 @as(u32, if (options.execute) posix.X_OK else 0);
27582741
2759 try current_thread.beginSyscall();
2742 const syscall: Syscall = try .start();
27602743 while (true) {
27612744 switch (posix.errno(posix.system.faccessat(dir.handle, sub_path_posix, mode, flags))) {
27622745 .SUCCESS => {
2763 current_thread.endSyscall();
2746 syscall.finish();
27642747 return;
27652748 },
27662749 .INTR => {
2767 try current_thread.checkCancel();
2750 try syscall.checkCancel();
27682751 continue;
27692752 },
27702753 else => |e| {
2771 current_thread.endSyscall();
2754 syscall.finish();
27722755 switch (e) {
27732756 .ACCES => return error.AccessDenied,
27742757 .PERM => return error.PermissionDenied,
......@@ -2798,26 +2781,26 @@ fn dirAccessWasi(
27982781) Dir.AccessError!void {
27992782 if (builtin.link_libc) return dirAccessPosix(userdata, dir, sub_path, options);
28002783 const t: *Threaded = @ptrCast(@alignCast(userdata));
2801 const current_thread = Thread.getCurrent(t);
2784 _ = t;
28022785 const wasi = std.os.wasi;
28032786 const flags: wasi.lookupflags_t = .{
28042787 .SYMLINK_FOLLOW = options.follow_symlinks,
28052788 };
28062789 var stat: wasi.filestat_t = undefined;
28072790
2808 try current_thread.beginSyscall();
2791 const syscall: Syscall = try .start();
28092792 while (true) {
28102793 switch (wasi.path_filestat_get(dir.handle, flags, sub_path.ptr, sub_path.len, &stat)) {
28112794 .SUCCESS => {
2812 current_thread.endSyscall();
2795 syscall.finish();
28132796 break;
28142797 },
28152798 .INTR => {
2816 try current_thread.checkCancel();
2799 try syscall.checkCancel();
28172800 continue;
28182801 },
28192802 else => |e| {
2820 current_thread.endSyscall();
2803 syscall.finish();
28212804 switch (e) {
28222805 .INVAL => |err| return errnoBug(err),
28232806 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
......@@ -2869,8 +2852,8 @@ fn dirAccessWindows(
28692852 options: Dir.AccessOptions,
28702853) Dir.AccessError!void {
28712854 const t: *Threaded = @ptrCast(@alignCast(userdata));
2872 const current_thread = Thread.getCurrent(t);
2873 try current_thread.checkCancel();
2855 _ = t;
2856 try Thread.checkCancel();
28742857
28752858 _ = options; // TODO
28762859
......@@ -2921,7 +2904,7 @@ fn dirCreateFilePosix(
29212904 flags: File.CreateFlags,
29222905) File.OpenError!File {
29232906 const t: *Threaded = @ptrCast(@alignCast(userdata));
2924 const current_thread = Thread.getCurrent(t);
2907 _ = t;
29252908
29262909 var path_buffer: [posix.PATH_MAX]u8 = undefined;
29272910 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
......@@ -2950,49 +2933,51 @@ fn dirCreateFilePosix(
29502933 },
29512934 };
29522935
2953 try current_thread.beginSyscall();
2954 const fd: posix.fd_t = while (true) {
2955 const rc = openat_sym(dir.handle, sub_path_posix, os_flags, flags.permissions.toMode());
2956 switch (posix.errno(rc)) {
2957 .SUCCESS => {
2958 current_thread.endSyscall();
2959 break @intCast(rc);
2960 },
2961 .INTR => {
2962 try current_thread.checkCancel();
2963 continue;
2964 },
2965 else => |e| {
2966 current_thread.endSyscall();
2967 switch (e) {
2968 .FAULT => |err| return errnoBug(err),
2969 .INVAL => return error.BadPathName,
2970 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
2971 .ACCES => return error.AccessDenied,
2972 .FBIG => return error.FileTooBig,
2973 .OVERFLOW => return error.FileTooBig,
2974 .ISDIR => return error.IsDir,
2975 .LOOP => return error.SymLinkLoop,
2976 .MFILE => return error.ProcessFdQuotaExceeded,
2977 .NAMETOOLONG => return error.NameTooLong,
2978 .NFILE => return error.SystemFdQuotaExceeded,
2979 .NODEV => return error.NoDevice,
2980 .NOENT => return error.FileNotFound,
2981 .SRCH => return error.FileNotFound, // Linux when accessing procfs.
2982 .NOMEM => return error.SystemResources,
2983 .NOSPC => return error.NoSpaceLeft,
2984 .NOTDIR => return error.NotDir,
2985 .PERM => return error.PermissionDenied,
2986 .EXIST => return error.PathAlreadyExists,
2987 .BUSY => return error.DeviceBusy,
2988 .OPNOTSUPP => return error.FileLocksUnsupported,
2989 .AGAIN => return error.WouldBlock,
2990 .TXTBSY => return error.FileBusy,
2991 .NXIO => return error.NoDevice,
2992 .ILSEQ => return error.BadPathName,
2993 else => |err| return posix.unexpectedErrno(err),
2994 }
2995 },
2936 const fd: posix.fd_t = fd: {
2937 const syscall: Syscall = try .start();
2938 while (true) {
2939 const rc = openat_sym(dir.handle, sub_path_posix, os_flags, flags.permissions.toMode());
2940 switch (posix.errno(rc)) {
2941 .SUCCESS => {
2942 syscall.finish();
2943 break :fd @intCast(rc);
2944 },
2945 .INTR => {
2946 try syscall.checkCancel();
2947 continue;
2948 },
2949 else => |e| {
2950 syscall.finish();
2951 switch (e) {
2952 .FAULT => |err| return errnoBug(err),
2953 .INVAL => return error.BadPathName,
2954 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
2955 .ACCES => return error.AccessDenied,
2956 .FBIG => return error.FileTooBig,
2957 .OVERFLOW => return error.FileTooBig,
2958 .ISDIR => return error.IsDir,
2959 .LOOP => return error.SymLinkLoop,
2960 .MFILE => return error.ProcessFdQuotaExceeded,
2961 .NAMETOOLONG => return error.NameTooLong,
2962 .NFILE => return error.SystemFdQuotaExceeded,
2963 .NODEV => return error.NoDevice,
2964 .NOENT => return error.FileNotFound,
2965 .SRCH => return error.FileNotFound, // Linux when accessing procfs.
2966 .NOMEM => return error.SystemResources,
2967 .NOSPC => return error.NoSpaceLeft,
2968 .NOTDIR => return error.NotDir,
2969 .PERM => return error.PermissionDenied,
2970 .EXIST => return error.PathAlreadyExists,
2971 .BUSY => return error.DeviceBusy,
2972 .OPNOTSUPP => return error.FileLocksUnsupported,
2973 .AGAIN => return error.WouldBlock,
2974 .TXTBSY => return error.FileBusy,
2975 .NXIO => return error.NoDevice,
2976 .ILSEQ => return error.BadPathName,
2977 else => |err| return posix.unexpectedErrno(err),
2978 }
2979 },
2980 }
29962981 }
29972982 };
29982983 errdefer posix.close(fd);
......@@ -3005,19 +2990,19 @@ fn dirCreateFilePosix(
30052990 .exclusive => posix.LOCK.EX | lock_nonblocking,
30062991 };
30072992
3008 try current_thread.beginSyscall();
2993 const syscall: Syscall = try .start();
30092994 while (true) {
30102995 switch (posix.errno(posix.system.flock(fd, lock_flags))) {
30112996 .SUCCESS => {
3012 current_thread.endSyscall();
2997 syscall.finish();
30132998 break;
30142999 },
30153000 .INTR => {
3016 try current_thread.checkCancel();
3001 try syscall.checkCancel();
30173002 continue;
30183003 },
30193004 else => |e| {
3020 current_thread.endSyscall();
3005 syscall.finish();
30213006 switch (e) {
30223007 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
30233008 .INVAL => |err| return errnoBug(err), // invalid parameters
......@@ -3032,40 +3017,42 @@ fn dirCreateFilePosix(
30323017 }
30333018
30343019 if (have_flock_open_flags and flags.lock_nonblocking) {
3035 try current_thread.beginSyscall();
3036 var fl_flags: usize = while (true) {
3037 const rc = posix.system.fcntl(fd, posix.F.GETFL, @as(usize, 0));
3038 switch (posix.errno(rc)) {
3039 .SUCCESS => {
3040 current_thread.endSyscall();
3041 break @intCast(rc);
3042 },
3043 .INTR => {
3044 try current_thread.checkCancel();
3045 continue;
3046 },
3047 else => |err| {
3048 current_thread.endSyscall();
3049 return posix.unexpectedErrno(err);
3050 },
3020 var fl_flags: usize = fl: {
3021 const syscall: Syscall = try .start();
3022 while (true) {
3023 const rc = posix.system.fcntl(fd, posix.F.GETFL, @as(usize, 0));
3024 switch (posix.errno(rc)) {
3025 .SUCCESS => {
3026 syscall.finish();
3027 break :fl @intCast(rc);
3028 },
3029 .INTR => {
3030 try syscall.checkCancel();
3031 continue;
3032 },
3033 else => |err| {
3034 syscall.finish();
3035 return posix.unexpectedErrno(err);
3036 },
3037 }
30513038 }
30523039 };
30533040
30543041 fl_flags |= @as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK"));
30553042
3056 try current_thread.beginSyscall();
3043 const syscall: Syscall = try .start();
30573044 while (true) {
30583045 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFL, fl_flags))) {
30593046 .SUCCESS => {
3060 current_thread.endSyscall();
3047 syscall.finish();
30613048 break;
30623049 },
30633050 .INTR => {
3064 try current_thread.checkCancel();
3051 try syscall.checkCancel();
30653052 continue;
30663053 },
30673054 else => |err| {
3068 current_thread.endSyscall();
3055 syscall.finish();
30693056 return posix.unexpectedErrno(err);
30703057 },
30713058 }
......@@ -3083,8 +3070,8 @@ fn dirCreateFileWindows(
30833070) File.OpenError!File {
30843071 const w = windows;
30853072 const t: *Threaded = @ptrCast(@alignCast(userdata));
3086 const current_thread = Thread.getCurrent(t);
3087 try current_thread.checkCancel();
3073 _ = t;
3074 try Thread.checkCancel();
30883075
30893076 const sub_path_w_array = try w.sliceToPrefixedFileW(dir.handle, sub_path);
30903077 const sub_path_w = sub_path_w_array.span();
......@@ -3143,7 +3130,7 @@ fn dirCreateFileWasi(
31433130 flags: File.CreateFlags,
31443131) File.OpenError!File {
31453132 const t: *Threaded = @ptrCast(@alignCast(userdata));
3146 const current_thread = Thread.getCurrent(t);
3133 _ = t;
31473134 const wasi = std.os.wasi;
31483135 const lookup_flags: wasi.lookupflags_t = .{};
31493136 const oflags: wasi.oflags_t = .{
......@@ -3171,19 +3158,19 @@ fn dirCreateFileWasi(
31713158 };
31723159 const inheriting: wasi.rights_t = .{};
31733160 var fd: posix.fd_t = undefined;
3174 try current_thread.beginSyscall();
3161 const syscall: Syscall = try .start();
31753162 while (true) {
31763163 switch (wasi.path_open(dir.handle, lookup_flags, sub_path.ptr, sub_path.len, oflags, base, inheriting, fdflags, &fd)) {
31773164 .SUCCESS => {
3178 current_thread.endSyscall();
3165 syscall.finish();
31793166 return .{ .handle = fd };
31803167 },
31813168 .INTR => {
3182 try current_thread.checkCancel();
3169 try syscall.checkCancel();
31833170 continue;
31843171 },
31853172 else => |e| {
3186 current_thread.endSyscall();
3173 syscall.finish();
31873174 switch (e) {
31883175 .FAULT => |err| return errnoBug(err),
31893176 .INVAL => return error.BadPathName,
......@@ -3226,7 +3213,6 @@ fn dirOpenFilePosix(
32263213 flags: File.OpenFlags,
32273214) File.OpenError!File {
32283215 const t: *Threaded = @ptrCast(@alignCast(userdata));
3229 const current_thread = Thread.getCurrent(t);
32303216
32313217 var path_buffer: [posix.PATH_MAX]u8 = undefined;
32323218 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
......@@ -3266,133 +3252,137 @@ fn dirOpenFilePosix(
32663252 },
32673253 };
32683254
3269 try current_thread.beginSyscall();
3270 const fd: posix.fd_t = while (true) {
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();
3255 const fd: posix.fd_t = fd: {
3256 const syscall: Syscall = try .start();
33363257 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)) {
33383260 .SUCCESS => {
3339 current_thread.endSyscall();
3340 break;
3261 syscall.finish();
3262 break :fd @intCast(rc);
33413263 },
33423264 .INTR => {
3343 try current_thread.checkCancel();
3265 try syscall.checkCancel();
33443266 continue;
33453267 },
33463268 else => |e| {
3347 current_thread.endSyscall();
3269 syscall.finish();
33483270 switch (e) {
3271 .FAULT => |err| return errnoBug(err),
3272 .INVAL => return error.BadPathName,
33493273 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
3350 .INVAL => |err| return errnoBug(err), // invalid parameters
3351 .NOLCK => return error.SystemResources,
3352 .AGAIN => return error.WouldBlock,
3274 .ACCES => return error.AccessDenied,
3275 .FBIG => return error.FileTooBig,
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,
33533291 .OPNOTSUPP => return error.FileLocksUnsupported,
3292 .AGAIN => return error.WouldBlock,
3293 .TXTBSY => return error.FileBusy,
3294 .NXIO => return error.NoDevice,
3295 .ILSEQ => return error.BadPathName,
33543296 else => |err| return posix.unexpectedErrno(err),
33553297 }
33563298 },
33573299 }
33583300 }
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;
33593314 }
33603315
3361 if (have_flock_open_flags and flags.lock_nonblocking) {
3362 try current_thread.beginSyscall();
3363 var fl_flags: usize = while (true) {
3364 const rc = posix.system.fcntl(fd, posix.F.GETFL, @as(usize, 0));
3365 switch (posix.errno(rc)) {
3316 if (have_flock and !have_flock_open_flags and flags.lock != .none) {
3317 const lock_nonblocking: i32 = if (flags.lock_nonblocking) posix.LOCK.NB else 0;
3318 const lock_flags = switch (flags.lock) {
3319 .none => unreachable,
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))) {
33663326 .SUCCESS => {
3367 current_thread.endSyscall();
3368 break @intCast(rc);
3327 syscall.finish();
3328 break;
33693329 },
33703330 .INTR => {
3371 try current_thread.checkCancel();
3331 try syscall.checkCancel();
33723332 continue;
33733333 },
3374 else => |err| {
3375 current_thread.endSyscall();
3376 return posix.unexpectedErrno(err);
3334 else => |e| {
3335 syscall.finish();
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 }
33773344 },
33783345 }
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 }
33793369 };
33803370
33813371 fl_flags |= @as(usize, 1 << @bitOffsetOf(posix.O, "NONBLOCK"));
33823372
3383 try current_thread.beginSyscall();
3373 const syscall: Syscall = try .start();
33843374 while (true) {
33853375 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFL, fl_flags))) {
33863376 .SUCCESS => {
3387 current_thread.endSyscall();
3377 syscall.finish();
33883378 break;
33893379 },
33903380 .INTR => {
3391 try current_thread.checkCancel();
3381 try syscall.checkCancel();
33923382 continue;
33933383 },
33943384 else => |err| {
3395 current_thread.endSyscall();
3385 syscall.finish();
33963386 return posix.unexpectedErrno(err);
33973387 },
33983388 }
......@@ -3425,7 +3415,7 @@ pub fn dirOpenFileWtf16(
34253415 if (!allow_directory and std.mem.eql(u16, sub_path_w, &.{'.'})) return error.IsDir;
34263416 if (!allow_directory and std.mem.eql(u16, sub_path_w, &.{ '.', '.' })) return error.IsDir;
34273417 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;
34293419 const w = windows;
34303420
34313421 var nt_name: w.UNICODE_STRING = .{
......@@ -3448,7 +3438,7 @@ pub fn dirOpenFileWtf16(
34483438 var attempt: u5 = 0;
34493439
34503440 const handle = while (true) {
3451 try current_thread.checkCancel();
3441 try Thread.checkCancel();
34523442
34533443 var result: w.HANDLE = undefined;
34543444 const rc = w.ntdll.NtCreateFile(
......@@ -3555,7 +3545,6 @@ fn dirOpenFileWasi(
35553545) File.OpenError!File {
35563546 if (builtin.link_libc) return dirOpenFilePosix(userdata, dir, sub_path, flags);
35573547 const t: *Threaded = @ptrCast(@alignCast(userdata));
3558 const current_thread = Thread.getCurrent(t);
35593548 const wasi = std.os.wasi;
35603549 var base: std.os.wasi.rights_t = .{};
35613550 // POLL_FD_READWRITE only grants extra rights if the corresponding FD_READ and/or FD_WRITE
......@@ -3585,19 +3574,19 @@ fn dirOpenFileWasi(
35853574 const inheriting: wasi.rights_t = .{};
35863575 const fdflags: wasi.fdflags_t = .{};
35873576 var fd: posix.fd_t = undefined;
3588 try current_thread.beginSyscall();
3577 const syscall: Syscall = try .start();
35893578 while (true) {
35903579 switch (wasi.path_open(dir.handle, lookup_flags, sub_path.ptr, sub_path.len, oflags, base, inheriting, fdflags, &fd)) {
35913580 .SUCCESS => {
3592 current_thread.endSyscall();
3581 syscall.finish();
35933582 break;
35943583 },
35953584 .INTR => {
3596 try current_thread.checkCancel();
3585 try syscall.checkCancel();
35973586 continue;
35983587 },
35993588 else => |e| {
3600 current_thread.endSyscall();
3589 syscall.finish();
36013590 switch (e) {
36023591 .FAULT => |err| return errnoBug(err),
36033592 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
......@@ -3654,14 +3643,13 @@ fn dirOpenDirPosix(
36543643 options: Dir.OpenOptions,
36553644) Dir.OpenError!Dir {
36563645 const t: *Threaded = @ptrCast(@alignCast(userdata));
3646 _ = t;
36573647
36583648 if (is_windows) {
36593649 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);
36613651 }
36623652
3663 const current_thread = Thread.getCurrent(t);
3664
36653653 var path_buffer: [posix.PATH_MAX]u8 = undefined;
36663654 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
36673655
......@@ -3682,20 +3670,20 @@ fn dirOpenDirPosix(
36823670 if (@hasField(posix.O, "PATH") and !options.iterate)
36833671 flags.PATH = true;
36843672
3685 try current_thread.beginSyscall();
3673 const syscall: Syscall = try .start();
36863674 while (true) {
36873675 const rc = openat_sym(dir.handle, sub_path_posix, flags, @as(usize, 0));
36883676 switch (posix.errno(rc)) {
36893677 .SUCCESS => {
3690 current_thread.endSyscall();
3678 syscall.finish();
36913679 return .{ .handle = @intCast(rc) };
36923680 },
36933681 .INTR => {
3694 try current_thread.checkCancel();
3682 try syscall.checkCancel();
36953683 continue;
36963684 },
36973685 else => |e| {
3698 current_thread.endSyscall();
3686 syscall.finish();
36993687 switch (e) {
37003688 .FAULT => |err| return errnoBug(err),
37013689 .INVAL => return error.BadPathName,
......@@ -3727,27 +3715,27 @@ fn dirOpenDirHaiku(
37273715 options: Dir.OpenOptions,
37283716) Dir.OpenError!Dir {
37293717 const t: *Threaded = @ptrCast(@alignCast(userdata));
3730 const current_thread = Thread.getCurrent(t);
3718 _ = t;
37313719
37323720 var path_buffer: [posix.PATH_MAX]u8 = undefined;
37333721 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
37343722
37353723 _ = options;
37363724
3737 try current_thread.beginSyscall();
3725 const syscall: Syscall = try .start();
37383726 while (true) {
37393727 const rc = posix.system._kern_open_dir(dir.handle, sub_path_posix);
37403728 if (rc >= 0) {
3741 current_thread.endSyscall();
3729 syscall.finish();
37423730 return .{ .handle = rc };
37433731 }
37443732 switch (@as(posix.E, @enumFromInt(rc))) {
37453733 .INTR => {
3746 try current_thread.checkCancel();
3734 try syscall.checkCancel();
37473735 continue;
37483736 },
37493737 else => |e| {
3750 current_thread.endSyscall();
3738 syscall.finish();
37513739 switch (e) {
37523740 .FAULT => |err| return errnoBug(err),
37533741 .INVAL => |err| return errnoBug(err),
......@@ -3771,12 +3759,10 @@ fn dirOpenDirHaiku(
37713759}
37723760
37733761pub fn dirOpenDirWindows(
3774 t: *Io.Threaded,
37753762 dir: Dir,
37763763 sub_path_w: [:0]const u16,
37773764 options: Dir.OpenOptions,
37783765) Dir.OpenError!Dir {
3779 const current_thread = Thread.getCurrent(t);
37803766 const w = windows;
37813767
37823768 const path_len_bytes: u16 = @intCast(sub_path_w.len * 2);
......@@ -3787,7 +3773,7 @@ pub fn dirOpenDirWindows(
37873773 };
37883774 var io_status_block: w.IO_STATUS_BLOCK = undefined;
37893775 var result: Dir = .{ .handle = undefined };
3790 try current_thread.checkCancel();
3776 try Thread.checkCancel();
37913777 const rc = w.ntdll.NtCreateFile(
37923778 &result.handle,
37933779 // TODO remove some of these flags if options.access_sub_paths is false
......@@ -3861,7 +3847,7 @@ const dirRead = switch (native_os) {
38613847fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
38623848 const linux = std.os.linux;
38633849 const t: *Threaded = @ptrCast(@alignCast(userdata));
3864 const current_thread = Thread.getCurrent(t);
3850 _ = t;
38653851 var buffer_index: usize = 0;
38663852 while (buffer.len - buffer_index != 0) {
38673853 if (dr.end - dr.index == 0) {
......@@ -3869,26 +3855,26 @@ fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir
38693855 // buffered data.
38703856 if (buffer_index != 0) break;
38713857 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) {
38733859 error.Unseekable => return error.Unexpected,
38743860 else => |e| return e,
38753861 };
38763862 dr.state = .reading;
38773863 }
3878 try current_thread.beginSyscall();
3864 const syscall: Syscall = try .start();
38793865 const n = while (true) {
38803866 const rc = linux.getdents64(dr.dir.handle, dr.buffer.ptr, dr.buffer.len);
38813867 switch (linux.errno(rc)) {
38823868 .SUCCESS => {
3883 current_thread.endSyscall();
3869 syscall.finish();
38843870 break rc;
38853871 },
38863872 .INTR => {
3887 try current_thread.checkCancel();
3873 try syscall.checkCancel();
38883874 continue;
38893875 },
38903876 else => |e| {
3891 current_thread.endSyscall();
3877 syscall.finish();
38923878 switch (e) {
38933879 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability.
38943880 .FAULT => |err| return errnoBug(err),
......@@ -3958,7 +3944,7 @@ fn dirReadLinux(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir
39583944
39593945fn dirReadDarwin(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
39603946 const t: *Threaded = @ptrCast(@alignCast(userdata));
3961 const current_thread = Thread.getCurrent(t);
3947 _ = t;
39623948 const Header = extern struct {
39633949 seek: i64,
39643950 };
......@@ -3977,27 +3963,27 @@ fn dirReadDarwin(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Di
39773963 // buffered data.
39783964 if (buffer_index != 0) break;
39793965 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) {
39813967 error.Unseekable => return error.Unexpected,
39823968 else => |e| return e,
39833969 };
39843970 dr.state = .reading;
39853971 }
39863972 const dents_buffer = dr.buffer[header_end..];
3987 try current_thread.beginSyscall();
3973 const syscall: Syscall = try .start();
39883974 const n: usize = while (true) {
39893975 const rc = posix.system.getdirentries(dr.dir.handle, dents_buffer.ptr, dents_buffer.len, &header.seek);
39903976 switch (posix.errno(rc)) {
39913977 .SUCCESS => {
3992 current_thread.endSyscall();
3978 syscall.finish();
39933979 break @intCast(rc);
39943980 },
39953981 .INTR => {
3996 try current_thread.checkCancel();
3982 try syscall.checkCancel();
39973983 continue;
39983984 },
39993985 else => |e| {
4000 current_thread.endSyscall();
3986 syscall.finish();
40013987 switch (e) {
40023988 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability.
40033989 .FAULT => |err| return errnoBug(err),
......@@ -4046,7 +4032,7 @@ fn dirReadDarwin(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Di
40464032
40474033fn dirReadBsd(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
40484034 const t: *Threaded = @ptrCast(@alignCast(userdata));
4049 const current_thread = Thread.getCurrent(t);
4035 _ = t;
40504036 var buffer_index: usize = 0;
40514037 while (buffer.len - buffer_index != 0) {
40524038 if (dr.end - dr.index == 0) {
......@@ -4054,26 +4040,26 @@ fn dirReadBsd(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.R
40544040 // buffered data.
40554041 if (buffer_index != 0) break;
40564042 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) {
40584044 error.Unseekable => return error.Unexpected,
40594045 else => |e| return e,
40604046 };
40614047 dr.state = .reading;
40624048 }
4063 try current_thread.beginSyscall();
4049 const syscall: Syscall = try .start();
40644050 const n: usize = while (true) {
40654051 const rc = posix.system.getdents(dr.dir.handle, dr.buffer.ptr, dr.buffer.len);
40664052 switch (posix.errno(rc)) {
40674053 .SUCCESS => {
4068 current_thread.endSyscall();
4054 syscall.finish();
40694055 break @intCast(rc);
40704056 },
40714057 .INTR => {
4072 try current_thread.checkCancel();
4058 try syscall.checkCancel();
40734059 continue;
40744060 },
40754061 else => |e| {
4076 current_thread.endSyscall();
4062 syscall.finish();
40774063 switch (e) {
40784064 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability
40794065 .FAULT => |err| return errnoBug(err),
......@@ -4140,7 +4126,7 @@ fn dirReadBsd(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.R
41404126
41414127fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
41424128 const t: *Threaded = @ptrCast(@alignCast(userdata));
4143 const current_thread = Thread.getCurrent(t);
4129 _ = t;
41444130 var buffer_index: usize = 0;
41454131 while (buffer.len - buffer_index != 0) {
41464132 if (dr.end - dr.index == 0) {
......@@ -4148,26 +4134,26 @@ fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) D
41484134 // buffered data.
41494135 if (buffer_index != 0) break;
41504136 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) {
41524138 error.Unseekable => return error.Unexpected,
41534139 else => |e| return e,
41544140 };
41554141 dr.state = .reading;
41564142 }
4157 try current_thread.beginSyscall();
4143 const syscall: Syscall = try .start();
41584144 const n: usize = while (true) {
41594145 const rc = posix.system.getdents(dr.dir.handle, dr.buffer.ptr, dr.buffer.len);
41604146 switch (posix.errno(rc)) {
41614147 .SUCCESS => {
4162 current_thread.endSyscall();
4148 syscall.finish();
41634149 break rc;
41644150 },
41654151 .INTR => {
4166 try current_thread.checkCancel();
4152 try syscall.checkCancel();
41674153 continue;
41684154 },
41694155 else => |e| {
4170 current_thread.endSyscall();
4156 syscall.finish();
41714157 switch (e) {
41724158 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability
41734159 .FAULT => |err| return errnoBug(err),
......@@ -4193,7 +4179,7 @@ fn dirReadIllumos(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) D
41934179 if (std.mem.eql(u8, name, ".") or std.mem.eql(u8, name, "..")) continue;
41944180
41954181 // 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
41984184 buffer[buffer_index] = .{
41994185 .name = name,
......@@ -4214,7 +4200,7 @@ fn dirReadHaiku(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir
42144200
42154201fn dirReadWindows(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.Reader.Error!usize {
42164202 const t: *Threaded = @ptrCast(@alignCast(userdata));
4217 const current_thread = Thread.getCurrent(t);
4203 _ = t;
42184204 const w = windows;
42194205
42204206 // 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
42784264 // buffered data.
42794265 if (buffer_index != 0) break;
42804266
4281 try current_thread.checkCancel();
4267 try Thread.checkCancel();
42824268 var io_status_block: w.IO_STATUS_BLOCK = undefined;
42834269 const rc = w.ntdll.NtQueryDirectoryFile(
42844270 dr.dir.handle,
......@@ -4364,7 +4350,7 @@ fn dirReadWasi(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.
43644350 // complexity here.
43654351 const wasi = std.os.wasi;
43664352 const t: *Threaded = @ptrCast(@alignCast(userdata));
4367 const current_thread = Thread.getCurrent(t);
4353 _ = t;
43684354 const Header = extern struct {
43694355 cookie: u64,
43704356 };
......@@ -4390,19 +4376,19 @@ fn dirReadWasi(userdata: ?*anyopaque, dr: *Dir.Reader, buffer: []Dir.Entry) Dir.
43904376 }
43914377 const dents_buffer = dr.buffer[header_end..];
43924378 var n: usize = undefined;
4393 try current_thread.beginSyscall();
4379 const syscall: Syscall = try .start();
43944380 while (true) {
43954381 switch (wasi.fd_readdir(dr.dir.handle, dents_buffer.ptr, dents_buffer.len, header.cookie, &n)) {
43964382 .SUCCESS => {
4397 current_thread.endSyscall();
4383 syscall.finish();
43984384 break;
43994385 },
44004386 .INTR => {
4401 try current_thread.checkCancel();
4387 try syscall.checkCancel();
44024388 continue;
44034389 },
44044390 else => |e| {
4405 current_thread.endSyscall();
4391 syscall.finish();
44064392 switch (e) {
44074393 .BADF => |err| return errnoBug(err), // Dir is invalid or was opened without iteration ability.
44084394 .FAULT => |err| return errnoBug(err),
......@@ -4478,9 +4464,9 @@ const dirRealPathFile = switch (native_os) {
44784464
44794465fn dirRealPathFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, out_buffer: []u8) Dir.RealPathFileError!usize {
44804466 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
44854471 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,
45004486 break :blk res;
45014487 };
45024488 defer windows.CloseHandle(h_file);
4503 return realPathWindows(current_thread, h_file, out_buffer);
4489 return realPathWindows(h_file, out_buffer);
45044490}
45054491
4506fn realPathWindows(current_thread: *Thread, h_file: windows.HANDLE, out_buffer: []u8) File.RealPathError!usize {
4507 _ = current_thread; // TODO move GetFinalPathNameByHandle logic into std.Io.Threaded and add cancel checks
4492fn realPathWindows(h_file: windows.HANDLE, out_buffer: []u8) File.RealPathError!usize {
4493 // TODO move GetFinalPathNameByHandle logic into std.Io.Threaded and add cancel checks
45084494 var wide_buf: [windows.PATH_MAX_WIDE]u16 = undefined;
45094495 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
45194505 if (native_os == .wasi) return error.OperationUnsupported;
45204506
45214507 const t: *Threaded = @ptrCast(@alignCast(userdata));
4522 const current_thread = Thread.getCurrent(t);
4508 _ = t;
45234509
45244510 var path_buffer: [posix.PATH_MAX]u8 = undefined;
45254511 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
45264512
45274513 if (builtin.link_libc and dir.handle == posix.AT.FDCWD) {
45284514 if (out_buffer.len < posix.PATH_MAX) return error.NameTooLong;
4529 try current_thread.beginSyscall();
4515 const syscall: Syscall = try .start();
45304516 while (true) {
45314517 if (std.c.realpath(sub_path_posix, out_buffer.ptr)) |redundant_pointer| {
4532 current_thread.endSyscall();
4518 syscall.finish();
45334519 assert(redundant_pointer == out_buffer.ptr);
45344520 return std.mem.indexOfScalar(u8, out_buffer, 0) orelse out_buffer.len;
45354521 }
45364522 const err: posix.E = @enumFromInt(std.c._errno().*);
45374523 if (err == .INTR) {
4538 try current_thread.checkCancel();
4524 try syscall.checkCancel();
45394525 continue;
45404526 }
4541 current_thread.endSyscall();
4527 syscall.finish();
45424528 switch (err) {
45434529 .INVAL => return errnoBug(err),
45444530 .BADF => return errnoBug(err),
......@@ -4562,20 +4548,20 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o
45624548
45634549 const mode: posix.mode_t = 0;
45644550
4565 try current_thread.beginSyscall();
4551 const syscall: Syscall = try .start();
45664552 const fd: posix.fd_t = while (true) {
45674553 const rc = openat_sym(dir.handle, sub_path_posix, flags, mode);
45684554 switch (posix.errno(rc)) {
45694555 .SUCCESS => {
4570 current_thread.endSyscall();
4556 syscall.finish();
45714557 break @intCast(rc);
45724558 },
45734559 .INTR => {
4574 try current_thread.checkCancel();
4560 try syscall.checkCancel();
45754561 continue;
45764562 },
45774563 else => |e| {
4578 current_thread.endSyscall();
4564 syscall.finish();
45794565 switch (e) {
45804566 .FAULT => |err| return errnoBug(err),
45814567 .INVAL => return error.BadPathName,
......@@ -4605,7 +4591,7 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o
46054591 }
46064592 };
46074593 defer posix.close(fd);
4608 return realPathPosix(current_thread, fd, out_buffer);
4594 return realPathPosix(fd, out_buffer);
46094595}
46104596
46114597const dirRealPath = switch (native_os) {
......@@ -4616,14 +4602,14 @@ const dirRealPath = switch (native_os) {
46164602fn dirRealPathPosix(userdata: ?*anyopaque, dir: Dir, out_buffer: []u8) Dir.RealPathError!usize {
46174603 if (native_os == .wasi) return error.OperationUnsupported;
46184604 const t: *Threaded = @ptrCast(@alignCast(userdata));
4619 const current_thread = Thread.getCurrent(t);
4620 return realPathPosix(current_thread, dir.handle, out_buffer);
4605 _ = t;
4606 return realPathPosix(dir.handle, out_buffer);
46214607}
46224608
46234609fn dirRealPathWindows(userdata: ?*anyopaque, dir: Dir, out_buffer: []u8) Dir.RealPathError!usize {
46244610 const t: *Threaded = @ptrCast(@alignCast(userdata));
4625 const current_thread = Thread.getCurrent(t);
4626 return realPathWindows(current_thread, dir.handle, out_buffer);
4611 _ = t;
4612 return realPathWindows(dir.handle, out_buffer);
46274613}
46284614
46294615const fileRealPath = switch (native_os) {
......@@ -4634,35 +4620,35 @@ const fileRealPath = switch (native_os) {
46344620fn fileRealPathWindows(userdata: ?*anyopaque, file: File, out_buffer: []u8) File.RealPathError!usize {
46354621 if (native_os == .wasi) return error.OperationUnsupported;
46364622 const t: *Threaded = @ptrCast(@alignCast(userdata));
4637 const current_thread = Thread.getCurrent(t);
4638 return realPathWindows(current_thread, file.handle, out_buffer);
4623 _ = t;
4624 return realPathWindows(file.handle, out_buffer);
46394625}
46404626
46414627fn fileRealPathPosix(userdata: ?*anyopaque, file: File, out_buffer: []u8) File.RealPathError!usize {
46424628 if (native_os == .wasi) return error.OperationUnsupported;
46434629 const t: *Threaded = @ptrCast(@alignCast(userdata));
4644 const current_thread = Thread.getCurrent(t);
4645 return realPathPosix(current_thread, file.handle, out_buffer);
4630 _ = t;
4631 return realPathPosix(file.handle, out_buffer);
46464632}
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 {
46494635 switch (native_os) {
46504636 .netbsd, .dragonfly, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => {
46514637 var sufficient_buffer: [posix.PATH_MAX]u8 = undefined;
46524638 @memset(&sufficient_buffer, 0);
4653 try current_thread.beginSyscall();
4639 const syscall: Syscall = try .start();
46544640 while (true) {
46554641 switch (posix.errno(posix.system.fcntl(fd, posix.F.GETPATH, &sufficient_buffer))) {
46564642 .SUCCESS => {
4657 current_thread.endSyscall();
4643 syscall.finish();
46584644 break;
46594645 },
46604646 .INTR => {
4661 try current_thread.checkCancel();
4647 try syscall.checkCancel();
46624648 continue;
46634649 },
46644650 else => |e| {
4665 current_thread.endSyscall();
4651 syscall.finish();
46664652 switch (e) {
46674653 .ACCES => return error.AccessDenied,
46684654 .BADF => return error.FileNotFound,
......@@ -4684,21 +4670,21 @@ fn realPathPosix(current_thread: *Thread, fd: posix.fd_t, out_buffer: []u8) File
46844670 var procfs_buf: ["/proc/self/path/-2147483648\x00".len]u8 = undefined;
46854671 const template = if (native_os == .illumos) "/proc/self/path/{d}" else "/proc/self/fd/{d}";
46864672 const proc_path = std.fmt.bufPrintSentinel(&procfs_buf, template, .{fd}, 0) catch unreachable;
4687 try current_thread.beginSyscall();
4673 const syscall: Syscall = try .start();
46884674 while (true) {
46894675 const rc = posix.system.readlink(proc_path, out_buffer.ptr, out_buffer.len);
46904676 switch (posix.errno(rc)) {
46914677 .SUCCESS => {
4692 current_thread.endSyscall();
4678 syscall.finish();
46934679 const len: usize = @bitCast(rc);
46944680 return len;
46954681 },
46964682 .INTR => {
4697 try current_thread.checkCancel();
4683 try syscall.checkCancel();
46984684 continue;
46994685 },
47004686 else => |e| {
4701 current_thread.endSyscall();
4687 syscall.finish();
47024688 switch (e) {
47034689 .ACCES => return error.AccessDenied,
47044690 .FAULT => |err| return errnoBug(err),
......@@ -4718,23 +4704,23 @@ fn realPathPosix(current_thread: *Thread, fd: posix.fd_t, out_buffer: []u8) File
47184704 .freebsd => {
47194705 var k_file: std.c.kinfo_file = undefined;
47204706 k_file.structsize = std.c.KINFO_FILE_SIZE;
4721 try current_thread.beginSyscall();
4707 const syscall: Syscall = try .start();
47224708 while (true) {
47234709 switch (posix.errno(std.c.fcntl(fd, std.c.F.KINFO, @intFromPtr(&k_file)))) {
47244710 .SUCCESS => {
4725 current_thread.endSyscall();
4711 syscall.finish();
47264712 break;
47274713 },
47284714 .INTR => {
4729 try current_thread.checkCancel();
4715 try syscall.checkCancel();
47304716 continue;
47314717 },
47324718 .BADF => {
4733 current_thread.endSyscall();
4719 syscall.finish();
47344720 return error.FileNotFound;
47354721 },
47364722 else => |err| {
4737 current_thread.endSyscall();
4723 syscall.finish();
47384724 return posix.unexpectedErrno(err);
47394725 },
47404726 }
......@@ -4765,21 +4751,21 @@ fn dirDeleteFileWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) D
47654751fn dirDeleteFileWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.DeleteFileError!void {
47664752 if (builtin.link_libc) return dirDeleteFilePosix(userdata, dir, sub_path);
47674753 const t: *Threaded = @ptrCast(@alignCast(userdata));
4768 const current_thread = Thread.getCurrent(t);
4769 try current_thread.beginSyscall();
4754 _ = t;
4755 const syscall: Syscall = try .start();
47704756 while (true) {
47714757 const res = std.os.wasi.path_unlink_file(dir.handle, sub_path.ptr, sub_path.len);
47724758 switch (res) {
47734759 .SUCCESS => {
4774 current_thread.endSyscall();
4760 syscall.finish();
47754761 return;
47764762 },
47774763 .INTR => {
4778 try current_thread.checkCancel();
4764 try syscall.checkCancel();
47794765 continue;
47804766 },
47814767 else => |e| {
4782 current_thread.endSyscall();
4768 syscall.finish();
47834769 switch (e) {
47844770 .ACCES => return error.AccessDenied,
47854771 .PERM => return error.PermissionDenied,
......@@ -4806,20 +4792,20 @@ fn dirDeleteFileWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.
48064792
48074793fn dirDeleteFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.DeleteFileError!void {
48084794 const t: *Threaded = @ptrCast(@alignCast(userdata));
4809 const current_thread = Thread.getCurrent(t);
4795 _ = t;
48104796
48114797 var path_buffer: [posix.PATH_MAX]u8 = undefined;
48124798 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
48134799
4814 try current_thread.beginSyscall();
4800 const syscall: Syscall = try .start();
48154801 while (true) {
48164802 switch (posix.errno(posix.system.unlinkat(dir.handle, sub_path_posix, 0))) {
48174803 .SUCCESS => {
4818 current_thread.endSyscall();
4804 syscall.finish();
48194805 return;
48204806 },
48214807 .INTR => {
4822 try current_thread.checkCancel();
4808 try syscall.checkCancel();
48234809 continue;
48244810 },
48254811 // 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
48314817 // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them).
48324818 var st = std.mem.zeroes(posix.Stat);
48334819 while (true) {
4834 try current_thread.checkCancel();
4820 try syscall.checkCancel();
48354821 switch (posix.errno(fstatat_sym(dir.handle, sub_path_posix, &st, posix.AT.SYMLINK_NOFOLLOW))) {
48364822 .SUCCESS => {
4837 current_thread.endSyscall();
4823 syscall.finish();
48384824 break;
48394825 },
48404826 .INTR => continue,
48414827 else => {
4842 current_thread.endSyscall();
4828 syscall.finish();
48434829 return error.PermissionDenied;
48444830 },
48454831 }
......@@ -4851,12 +4837,12 @@ fn dirDeleteFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir
48514837 return error.PermissionDenied;
48524838 },
48534839 else => {
4854 current_thread.endSyscall();
4840 syscall.finish();
48554841 return error.PermissionDenied;
48564842 },
48574843 },
48584844 else => |e| {
4859 current_thread.endSyscall();
4845 syscall.finish();
48604846 switch (e) {
48614847 .ACCES => return error.AccessDenied,
48624848 .BUSY => return error.FileBusy,
......@@ -4896,10 +4882,10 @@ fn dirDeleteDirWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Di
48964882
48974883fn dirDeleteWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, remove_dir: bool) (Dir.DeleteDirError || Dir.DeleteFileError)!void {
48984884 const t: *Threaded = @ptrCast(@alignCast(userdata));
4899 const current_thread = Thread.getCurrent(t);
4885 _ = t;
49004886 const w = windows;
49014887
4902 try current_thread.checkCancel();
4888 try Thread.checkCancel();
49034889
49044890 const sub_path_w_buf = try w.sliceToPrefixedFileW(dir.handle, sub_path);
49054891 const sub_path_w = sub_path_w_buf.span();
......@@ -4979,7 +4965,7 @@ fn dirDeleteWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, remov
49794965 // The strategy here is just to try using FileDispositionInformationEx and fall back to
49804966 // FileDispositionInformation if the return value lets us know that some aspect of it is not supported.
49814967 const need_fallback = need_fallback: {
4982 try current_thread.checkCancel();
4968 try Thread.checkCancel();
49834969
49844970 // Deletion with posix semantics if the filesystem supports it.
49854971 const info: w.FILE.DISPOSITION.INFORMATION.EX = .{ .Flags = .{
......@@ -5010,7 +4996,7 @@ fn dirDeleteWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, remov
50104996 };
50114997
50124998 if (need_fallback) {
5013 try current_thread.checkCancel();
4999 try Thread.checkCancel();
50145000
50155001 // Deletion with file pending semantics, which requires waiting or moving
50165002 // files to get them removed (from here).
......@@ -5041,22 +5027,22 @@ fn dirDeleteDirWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.D
50415027 if (builtin.link_libc) return dirDeleteDirPosix(userdata, dir, sub_path);
50425028
50435029 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();
50475033 while (true) {
50485034 const res = std.os.wasi.path_remove_directory(dir.handle, sub_path.ptr, sub_path.len);
50495035 switch (res) {
50505036 .SUCCESS => {
5051 current_thread.endSyscall();
5037 syscall.finish();
50525038 return;
50535039 },
50545040 .INTR => {
5055 try current_thread.checkCancel();
5041 try syscall.checkCancel();
50565042 continue;
50575043 },
50585044 else => |e| {
5059 current_thread.endSyscall();
5045 syscall.finish();
50605046 switch (e) {
50615047 .ACCES => return error.AccessDenied,
50625048 .PERM => return error.PermissionDenied,
......@@ -5083,24 +5069,24 @@ fn dirDeleteDirWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.D
50835069
50845070fn dirDeleteDirPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8) Dir.DeleteDirError!void {
50855071 const t: *Threaded = @ptrCast(@alignCast(userdata));
5086 const current_thread = Thread.getCurrent(t);
5072 _ = t;
50875073
50885074 var path_buffer: [posix.PATH_MAX]u8 = undefined;
50895075 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
50905076
5091 try current_thread.beginSyscall();
5077 const syscall: Syscall = try .start();
50925078 while (true) {
50935079 switch (posix.errno(posix.system.unlinkat(dir.handle, sub_path_posix, posix.AT.REMOVEDIR))) {
50945080 .SUCCESS => {
5095 current_thread.endSyscall();
5081 syscall.finish();
50965082 return;
50975083 },
50985084 .INTR => {
5099 try current_thread.checkCancel();
5085 try syscall.checkCancel();
51005086 continue;
51015087 },
51025088 else => |e| {
5103 current_thread.endSyscall();
5089 syscall.finish();
51045090 switch (e) {
51055091 .ACCES => return error.AccessDenied,
51065092 .PERM => return error.PermissionDenied,
......@@ -5141,7 +5127,7 @@ fn dirRenameWindows(
51415127) Dir.RenameError!void {
51425128 const w = windows;
51435129 const t: *Threaded = @ptrCast(@alignCast(userdata));
5144 const current_thread = Thread.getCurrent(t);
5130 _ = t;
51455131
51465132 const old_path_w_buf = try windows.sliceToPrefixedFileW(old_dir.handle, old_sub_path);
51475133 const old_path_w = old_path_w_buf.span();
......@@ -5149,7 +5135,7 @@ fn dirRenameWindows(
51495135 const new_path_w = new_path_w_buf.span();
51505136 const replace_if_exists = true;
51515137
5152 try current_thread.checkCancel();
5138 try Thread.checkCancel();
51535139
51545140 const src_fd = w.OpenFile(old_path_w, .{
51555141 .dir = old_dir.handle,
......@@ -5258,18 +5244,18 @@ fn dirRenameWasi(
52585244 if (builtin.link_libc) return dirRenamePosix(userdata, old_dir, old_sub_path, new_dir, new_sub_path);
52595245
52605246 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();
52645250 while (true) {
52655251 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(),
52675253 .INTR => {
5268 try current_thread.checkCancel();
5254 try syscall.checkCancel();
52695255 continue;
52705256 },
52715257 else => |e| {
5272 current_thread.endSyscall();
5258 syscall.finish();
52735259 switch (e) {
52745260 .ACCES => return error.AccessDenied,
52755261 .PERM => return error.PermissionDenied,
......@@ -5306,7 +5292,7 @@ fn dirRenamePosix(
53065292 new_sub_path: []const u8,
53075293) Dir.RenameError!void {
53085294 const t: *Threaded = @ptrCast(@alignCast(userdata));
5309 const current_thread = Thread.getCurrent(t);
5295 _ = t;
53105296
53115297 var old_path_buffer: [posix.PATH_MAX]u8 = undefined;
53125298 var new_path_buffer: [posix.PATH_MAX]u8 = undefined;
......@@ -5314,16 +5300,16 @@ fn dirRenamePosix(
53145300 const old_sub_path_posix = try pathToPosix(old_sub_path, &old_path_buffer);
53155301 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();
53185304 while (true) {
53195305 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(),
53215307 .INTR => {
5322 try current_thread.checkCancel();
5308 try syscall.checkCancel();
53235309 continue;
53245310 },
53255311 else => |e| {
5326 current_thread.endSyscall();
5312 syscall.finish();
53275313 switch (e) {
53285314 .ACCES => return error.AccessDenied,
53295315 .PERM => return error.PermissionDenied,
......@@ -5365,10 +5351,10 @@ fn dirSymLinkWindows(
53655351 flags: Dir.SymLinkFlags,
53665352) Dir.SymLinkError!void {
53675353 const t: *Threaded = @ptrCast(@alignCast(userdata));
5368 const current_thread = Thread.getCurrent(t);
5354 _ = t;
53695355 const w = windows;
53705356
5371 try current_thread.checkCancel();
5357 try Thread.checkCancel();
53725358
53735359 // Target path does not use sliceToPrefixedFileW because certain paths
53745360 // are handled differently when creating a symlink than they would be
......@@ -5492,18 +5478,18 @@ fn dirSymLinkWasi(
54925478 if (builtin.link_libc) return dirSymLinkPosix(userdata, dir, target_path, sym_link_path, flags);
54935479
54945480 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();
54985484 while (true) {
54995485 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(),
55015487 .INTR => {
5502 try current_thread.checkCancel();
5488 try syscall.checkCancel();
55035489 continue;
55045490 },
55055491 else => |e| {
5506 current_thread.endSyscall();
5492 syscall.finish();
55075493 switch (e) {
55085494 .FAULT => |err| return errnoBug(err),
55095495 .INVAL => |err| return errnoBug(err),
......@@ -5538,7 +5524,7 @@ fn dirSymLinkPosix(
55385524) Dir.SymLinkError!void {
55395525 _ = flags;
55405526 const t: *Threaded = @ptrCast(@alignCast(userdata));
5541 const current_thread = Thread.getCurrent(t);
5527 _ = t;
55425528
55435529 var target_path_buffer: [posix.PATH_MAX]u8 = undefined;
55445530 var sym_link_path_buffer: [posix.PATH_MAX]u8 = undefined;
......@@ -5546,16 +5532,16 @@ fn dirSymLinkPosix(
55465532 const target_path_posix = try pathToPosix(target_path, &target_path_buffer);
55475533 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();
55505536 while (true) {
55515537 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(),
55535539 .INTR => {
5554 try current_thread.checkCancel();
5540 try syscall.checkCancel();
55555541 continue;
55565542 },
55575543 else => |e| {
5558 current_thread.endSyscall();
5544 syscall.finish();
55595545 switch (e) {
55605546 .FAULT => |err| return errnoBug(err),
55615547 .INVAL => |err| return errnoBug(err),
......@@ -5587,10 +5573,10 @@ const dirReadLink = switch (native_os) {
55875573
55885574fn dirReadLinkWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize {
55895575 const t: *Threaded = @ptrCast(@alignCast(userdata));
5590 const current_thread = Thread.getCurrent(t);
5576 _ = t;
55915577 const w = windows;
55925578
5593 try current_thread.checkCancel();
5579 try Thread.checkCancel();
55945580
55955581 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
56065592 if (builtin.link_libc) return dirReadLinkPosix(userdata, dir, sub_path, buffer);
56075593
56085594 const t: *Threaded = @ptrCast(@alignCast(userdata));
5609 const current_thread = Thread.getCurrent(t);
5595 _ = t;
56105596
56115597 var n: usize = undefined;
5612 try current_thread.beginSyscall();
5598 const syscall: Syscall = try .start();
56135599 while (true) {
56145600 switch (std.os.wasi.path_readlink(dir.handle, sub_path.ptr, sub_path.len, buffer.ptr, buffer.len, &n)) {
56155601 .SUCCESS => {
5616 current_thread.endSyscall();
5602 syscall.finish();
56175603 return n;
56185604 },
56195605 .INTR => {
5620 try current_thread.checkCancel();
5606 try syscall.checkCancel();
56215607 continue;
56225608 },
56235609 else => |e| {
5624 current_thread.endSyscall();
5610 syscall.finish();
56255611 switch (e) {
56265612 .ACCES => return error.AccessDenied,
56275613 .FAULT => |err| return errnoBug(err),
......@@ -5643,26 +5629,26 @@ fn dirReadLinkWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer
56435629
56445630fn dirReadLinkPosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize {
56455631 const t: *Threaded = @ptrCast(@alignCast(userdata));
5646 const current_thread = Thread.getCurrent(t);
5632 _ = t;
56475633
56485634 var sub_path_buffer: [posix.PATH_MAX]u8 = undefined;
56495635 const sub_path_posix = try pathToPosix(sub_path, &sub_path_buffer);
56505636
5651 try current_thread.beginSyscall();
5637 const syscall: Syscall = try .start();
56525638 while (true) {
56535639 const rc = posix.system.readlinkat(dir.handle, sub_path_posix, buffer.ptr, buffer.len);
56545640 switch (posix.errno(rc)) {
56555641 .SUCCESS => {
5656 current_thread.endSyscall();
5642 syscall.finish();
56575643 const len: usize = @bitCast(rc);
56585644 return len;
56595645 },
56605646 .INTR => {
5661 try current_thread.checkCancel();
5647 try syscall.checkCancel();
56625648 continue;
56635649 },
56645650 else => |e| {
5665 current_thread.endSyscall();
5651 syscall.finish();
56665652 switch (e) {
56675653 .ACCES => return error.AccessDenied,
56685654 .FAULT => |err| return errnoBug(err),
......@@ -5697,8 +5683,8 @@ fn dirSetPermissionsWindows(userdata: ?*anyopaque, dir: Dir, permissions: Dir.Pe
56975683fn dirSetPermissionsPosix(userdata: ?*anyopaque, dir: Dir, permissions: Dir.Permissions) Dir.SetPermissionsError!void {
56985684 if (@sizeOf(Dir.Permissions) == 0) return;
56995685 const t: *Threaded = @ptrCast(@alignCast(userdata));
5700 const current_thread = Thread.getCurrent(t);
5701 return setPermissionsPosix(current_thread, dir.handle, permissions.toMode());
5686 _ = t;
5687 return setPermissionsPosix(dir.handle, permissions.toMode());
57025688}
57035689
57045690fn dirSetFilePermissions(
......@@ -5711,7 +5697,6 @@ fn dirSetFilePermissions(
57115697 if (@sizeOf(Dir.Permissions) == 0) return;
57125698 if (is_windows) @panic("TODO implement dirSetFilePermissions windows");
57135699 const t: *Threaded = @ptrCast(@alignCast(userdata));
5714 const current_thread = Thread.getCurrent(t);
57155700
57165701 var path_buffer: [posix.PATH_MAX]u8 = undefined;
57175702 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
......@@ -5719,12 +5704,11 @@ fn dirSetFilePermissions(
57195704 const mode = permissions.toMode();
57205705 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);
57235708}
57245709
57255710fn posixFchmodat(
57265711 t: *Threaded,
5727 current_thread: *Thread,
57285712 dir_fd: posix.fd_t,
57295713 path: [*:0]const u8,
57305714 mode: posix.mode_t,
......@@ -5733,20 +5717,20 @@ fn posixFchmodat(
57335717 // No special handling for linux is needed if we can use the libc fallback
57345718 // or `flags` is empty. Glibc only added the fallback in 2.32.
57355719 if (have_fchmodat_flags or flags == 0) {
5736 try current_thread.beginSyscall();
5720 const syscall: Syscall = try .start();
57375721 while (true) {
57385722 const rc = if (have_fchmodat_flags or builtin.link_libc)
57395723 posix.system.fchmodat(dir_fd, path, mode, flags)
57405724 else
57415725 posix.system.fchmodat(dir_fd, path, mode);
57425726 switch (posix.errno(rc)) {
5743 .SUCCESS => return current_thread.endSyscall(),
5727 .SUCCESS => return syscall.finish(),
57445728 .INTR => {
5745 try current_thread.checkCancel();
5729 try syscall.checkCancel();
57465730 continue;
57475731 },
57485732 else => |e| {
5749 current_thread.endSyscall();
5733 syscall.finish();
57505734 switch (e) {
57515735 .BADF => |err| return errnoBug(err),
57525736 .FAULT => |err| return errnoBug(err),
......@@ -5771,20 +5755,20 @@ fn posixFchmodat(
57715755 }
57725756
57735757 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
57765760 comptime assert(native_os == .linux);
57775761
5778 try current_thread.beginSyscall();
5762 const syscall: Syscall = try .start();
57795763 while (true) {
57805764 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(),
57825766 .INTR => {
5783 try current_thread.checkCancel();
5767 try syscall.checkCancel();
57845768 continue;
57855769 },
57865770 else => |e| {
5787 current_thread.endSyscall();
5771 syscall.finish();
57885772 switch (e) {
57895773 .BADF => |err| return errnoBug(err),
57905774 .FAULT => |err| return errnoBug(err),
......@@ -5800,7 +5784,7 @@ fn posixFchmodat(
58005784 .ROFS => return error.ReadOnlyFileSystem,
58015785 .NOSYS => {
58025786 @atomicStore(UseFchmodat2, &t.use_fchmodat2, .disabled, .monotonic);
5803 return fchmodatFallback(current_thread, dir_fd, path, mode);
5787 return fchmodatFallback(dir_fd, path, mode);
58045788 },
58055789 else => |err| return posix.unexpectedErrno(err),
58065790 }
......@@ -5810,7 +5794,6 @@ fn posixFchmodat(
58105794}
58115795
58125796fn fchmodatFallback(
5813 current_thread: *Thread,
58145797 dir_fd: posix.fd_t,
58155798 path: [*:0]const u8,
58165799 mode: posix.mode_t,
......@@ -5828,64 +5811,68 @@ fn fchmodatFallback(
58285811 // 2. Stat the fd and check if it isn't a symbolic link.
58295812 // 3. Generate the procfs reference to the fd via `/proc/self/fd/{fd}`.
58305813 // 4. Pass the procfs path to `chmod` with the `mode`.
5831 try current_thread.beginSyscall();
5832 const path_fd: posix.fd_t = while (true) {
5833 const rc = posix.system.openat(dir_fd, path, .{
5834 .PATH = true,
5835 .NOFOLLOW = true,
5836 .CLOEXEC = true,
5837 }, @as(posix.mode_t, 0));
5838 switch (posix.errno(rc)) {
5839 .SUCCESS => {
5840 current_thread.endSyscall();
5841 break @intCast(rc);
5842 },
5843 .INTR => {
5844 try current_thread.checkCancel();
5845 continue;
5846 },
5847 else => |e| {
5848 current_thread.endSyscall();
5849 switch (e) {
5850 .FAULT => |err| return errnoBug(err),
5851 .INVAL => |err| return errnoBug(err),
5852 .ACCES => return error.AccessDenied,
5853 .PERM => return error.PermissionDenied,
5854 .LOOP => return error.SymLinkLoop,
5855 .MFILE => return error.ProcessFdQuotaExceeded,
5856 .NAMETOOLONG => return error.NameTooLong,
5857 .NFILE => return error.SystemFdQuotaExceeded,
5858 .NOENT => return error.FileNotFound,
5859 .NOMEM => return error.SystemResources,
5860 else => |err| return posix.unexpectedErrno(err),
5861 }
5862 },
5814 const path_fd: posix.fd_t = fd: {
5815 const syscall: Syscall = try .start();
5816 while (true) {
5817 const rc = posix.system.openat(dir_fd, path, .{
5818 .PATH = true,
5819 .NOFOLLOW = true,
5820 .CLOEXEC = true,
5821 }, @as(posix.mode_t, 0));
5822 switch (posix.errno(rc)) {
5823 .SUCCESS => {
5824 syscall.finish();
5825 break :fd @intCast(rc);
5826 },
5827 .INTR => {
5828 try syscall.checkCancel();
5829 continue;
5830 },
5831 else => |e| {
5832 syscall.finish();
5833 switch (e) {
5834 .FAULT => |err| return errnoBug(err),
5835 .INVAL => |err| return errnoBug(err),
5836 .ACCES => return error.AccessDenied,
5837 .PERM => return error.PermissionDenied,
5838 .LOOP => return error.SymLinkLoop,
5839 .MFILE => return error.ProcessFdQuotaExceeded,
5840 .NAMETOOLONG => return error.NameTooLong,
5841 .NFILE => return error.SystemFdQuotaExceeded,
5842 .NOENT => return error.FileNotFound,
5843 .NOMEM => return error.SystemResources,
5844 else => |err| return posix.unexpectedErrno(err),
5845 }
5846 },
5847 }
58635848 }
58645849 };
58655850 defer posix.close(path_fd);
58665851
5867 try current_thread.beginSyscall();
5868 const path_mode = while (true) {
5869 var statx = std.mem.zeroes(std.os.linux.Statx);
5870 switch (sys.errno(sys.statx(path_fd, "", posix.AT.EMPTY_PATH, .{ .TYPE = true }, &statx))) {
5871 .SUCCESS => {
5872 current_thread.endSyscall();
5873 if (!statx.mask.TYPE) return error.Unexpected;
5874 break statx.mode;
5875 },
5876 .INTR => {
5877 try current_thread.checkCancel();
5878 continue;
5879 },
5880 else => |e| {
5881 current_thread.endSyscall();
5882 switch (e) {
5883 .ACCES => return error.AccessDenied,
5884 .LOOP => return error.SymLinkLoop,
5885 .NOMEM => return error.SystemResources,
5886 else => |err| return posix.unexpectedErrno(err),
5887 }
5888 },
5852 const path_mode = mode: {
5853 const syscall: Syscall = try .start();
5854 while (true) {
5855 var statx = std.mem.zeroes(std.os.linux.Statx);
5856 switch (sys.errno(sys.statx(path_fd, "", posix.AT.EMPTY_PATH, .{ .TYPE = true }, &statx))) {
5857 .SUCCESS => {
5858 syscall.finish();
5859 if (!statx.mask.TYPE) return error.Unexpected;
5860 break :mode statx.mode;
5861 },
5862 .INTR => {
5863 try syscall.checkCancel();
5864 continue;
5865 },
5866 else => |e| {
5867 syscall.finish();
5868 switch (e) {
5869 .ACCES => return error.AccessDenied,
5870 .LOOP => return error.SymLinkLoop,
5871 .NOMEM => return error.SystemResources,
5872 else => |err| return posix.unexpectedErrno(err),
5873 }
5874 },
5875 }
58895876 }
58905877 };
58915878
......@@ -5895,16 +5882,16 @@ fn fchmodatFallback(
58955882
58965883 var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;
58975884 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();
58995886 while (true) {
59005887 switch (posix.errno(posix.system.chmod(proc_path, mode))) {
5901 .SUCCESS => return current_thread.endSyscall(),
5888 .SUCCESS => return syscall.finish(),
59025889 .INTR => {
5903 try current_thread.checkCancel();
5890 try syscall.checkCancel();
59045891 continue;
59055892 },
59065893 else => |e| {
5907 current_thread.endSyscall();
5894 syscall.finish();
59085895 switch (e) {
59095896 .NOENT => return error.OperationUnsupported, // procfs not mounted.
59105897 .BADF => |err| return errnoBug(err),
......@@ -5940,24 +5927,24 @@ fn dirSetOwnerUnsupported(userdata: ?*anyopaque, dir: Dir, owner: ?File.Uid, gro
59405927fn dirSetOwnerPosix(userdata: ?*anyopaque, dir: Dir, owner: ?File.Uid, group: ?File.Gid) Dir.SetOwnerError!void {
59415928 if (!have_fchown) return error.Unexpected; // Unsupported OS, don't call this function.
59425929 const t: *Threaded = @ptrCast(@alignCast(userdata));
5943 const current_thread = Thread.getCurrent(t);
5930 _ = t;
59445931 const uid = owner orelse ~@as(posix.uid_t, 0);
59455932 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);
59475934}
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 {
59505937 comptime assert(have_fchown);
5951 try current_thread.beginSyscall();
5938 const syscall: Syscall = try .start();
59525939 while (true) {
59535940 switch (posix.errno(posix.system.fchown(fd, uid, gid))) {
5954 .SUCCESS => return current_thread.endSyscall(),
5941 .SUCCESS => return syscall.finish(),
59555942 .INTR => {
5956 try current_thread.checkCancel();
5943 try syscall.checkCancel();
59575944 continue;
59585945 },
59595946 else => |e| {
5960 current_thread.endSyscall();
5947 syscall.finish();
59615948 switch (e) {
59625949 .BADF => |err| return errnoBug(err), // likely fd refers to directory opened without `Dir.OpenOptions.iterate`
59635950 .FAULT => |err| return errnoBug(err),
......@@ -5987,12 +5974,11 @@ fn dirSetFileOwner(
59875974) Dir.SetFileOwnerError!void {
59885975 if (!have_fchown) return error.Unexpected; // Unsupported OS, don't call this function.
59895976 const t: *Threaded = @ptrCast(@alignCast(userdata));
5990 const current_thread = Thread.getCurrent(t);
5977 _ = t;
59915978
59925979 var path_buffer: [posix.PATH_MAX]u8 = undefined;
59935980 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
59945981
5995 _ = current_thread;
59965982 _ = dir;
59975983 _ = sub_path_posix;
59985984 _ = owner;
......@@ -6009,9 +5995,9 @@ const fileSync = switch (native_os) {
60095995
60105996fn fileSyncWindows(userdata: ?*anyopaque, file: File) File.SyncError!void {
60115997 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
60166002 if (windows.kernel32.FlushFileBuffers(file.handle) != 0)
60176003 return;
......@@ -6027,17 +6013,17 @@ fn fileSyncWindows(userdata: ?*anyopaque, file: File) File.SyncError!void {
60276013
60286014fn fileSyncPosix(userdata: ?*anyopaque, file: File) File.SyncError!void {
60296015 const t: *Threaded = @ptrCast(@alignCast(userdata));
6030 const current_thread = Thread.getCurrent(t);
6031 try current_thread.beginSyscall();
6016 _ = t;
6017 const syscall: Syscall = try .start();
60326018 while (true) {
60336019 switch (posix.errno(posix.system.fsync(file.handle))) {
6034 .SUCCESS => return current_thread.endSyscall(),
6020 .SUCCESS => return syscall.finish(),
60356021 .INTR => {
6036 try current_thread.checkCancel();
6022 try syscall.checkCancel();
60376023 continue;
60386024 },
60396025 else => |e| {
6040 current_thread.endSyscall();
6026 syscall.finish();
60416027 switch (e) {
60426028 .BADF => |err| return errnoBug(err),
60436029 .INVAL => |err| return errnoBug(err),
......@@ -6054,17 +6040,17 @@ fn fileSyncPosix(userdata: ?*anyopaque, file: File) File.SyncError!void {
60546040
60556041fn fileSyncWasi(userdata: ?*anyopaque, file: File) File.SyncError!void {
60566042 const t: *Threaded = @ptrCast(@alignCast(userdata));
6057 const current_thread = Thread.getCurrent(t);
6058 try current_thread.beginSyscall();
6043 _ = t;
6044 const syscall: Syscall = try .start();
60596045 while (true) {
60606046 switch (std.os.wasi.fd_sync(file.handle)) {
6061 .SUCCESS => return current_thread.endSyscall(),
6047 .SUCCESS => return syscall.finish(),
60626048 .INTR => {
6063 try current_thread.checkCancel();
6049 try syscall.checkCancel();
60646050 continue;
60656051 },
60666052 else => |e| {
6067 current_thread.endSyscall();
6053 syscall.finish();
60686054 switch (e) {
60696055 .BADF => |err| return errnoBug(err),
60706056 .INVAL => |err| return errnoBug(err),
......@@ -6081,33 +6067,33 @@ fn fileSyncWasi(userdata: ?*anyopaque, file: File) File.SyncError!void {
60816067
60826068fn fileIsTty(userdata: ?*anyopaque, file: File) Io.Cancelable!bool {
60836069 const t: *Threaded = @ptrCast(@alignCast(userdata));
6084 const current_thread = Thread.getCurrent(t);
6085 return isTty(current_thread, file);
6070 _ = t;
6071 return isTty(file);
60866072}
60876073
6088fn isTty(current_thread: *Thread, file: File) Io.Cancelable!bool {
6074fn isTty(file: File) Io.Cancelable!bool {
60896075 if (is_windows) {
6090 if (try isCygwinPty(current_thread, file)) return true;
6091 try current_thread.checkCancel();
6076 if (try isCygwinPty(file)) return true;
6077 try Thread.checkCancel();
60926078 var out: windows.DWORD = undefined;
60936079 return windows.kernel32.GetConsoleMode(file.handle, &out) != 0;
60946080 }
60956081
60966082 if (builtin.link_libc) {
6097 try current_thread.beginSyscall();
6083 const syscall: Syscall = try .start();
60986084 while (true) {
60996085 const rc = posix.system.isatty(file.handle);
61006086 switch (posix.errno(rc - 1)) {
61016087 .SUCCESS => {
6102 current_thread.endSyscall();
6088 syscall.finish();
61036089 return true;
61046090 },
61056091 .INTR => {
6106 try current_thread.checkCancel();
6092 try syscall.checkCancel();
61076093 continue;
61086094 },
61096095 else => {
6110 current_thread.endSyscall();
6096 syscall.finish();
61116097 return false;
61126098 },
61136099 }
......@@ -6131,22 +6117,22 @@ fn isTty(current_thread: *Thread, file: File) Io.Cancelable!bool {
61316117
61326118 if (native_os == .linux) {
61336119 const linux = std.os.linux;
6134 try current_thread.beginSyscall();
6120 const syscall: Syscall = try .start();
61356121 while (true) {
61366122 var wsz: posix.winsize = undefined;
61376123 const fd: usize = @bitCast(@as(isize, file.handle));
61386124 const rc = linux.syscall3(.ioctl, fd, linux.T.IOCGWINSZ, @intFromPtr(&wsz));
61396125 switch (linux.errno(rc)) {
61406126 .SUCCESS => {
6141 current_thread.endSyscall();
6127 syscall.finish();
61426128 return true;
61436129 },
61446130 .INTR => {
6145 try current_thread.checkCancel();
6131 try syscall.checkCancel();
61466132 continue;
61476133 },
61486134 else => {
6149 current_thread.endSyscall();
6135 syscall.finish();
61506136 return false;
61516137 },
61526138 }
......@@ -6158,10 +6144,10 @@ fn isTty(current_thread: *Thread, file: File) Io.Cancelable!bool {
61586144
61596145fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiEscapeCodesError!void {
61606146 const t: *Threaded = @ptrCast(@alignCast(userdata));
6161 const current_thread = Thread.getCurrent(t);
6147 _ = t;
61626148
61636149 if (is_windows) {
6164 try current_thread.checkCancel();
6150 try Thread.checkCancel();
61656151
61666152 // For Windows Terminal, VT Sequences processing is enabled by default.
61676153 var original_console_mode: windows.DWORD = 0;
......@@ -6181,30 +6167,30 @@ fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiE
61816167 // we end up matching the mode of Windows Terminal.
61826168 const requested_console_modes = windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING;
61836169 const console_mode = original_console_mode | requested_console_modes;
6184 try current_thread.checkCancel();
6170 try Thread.checkCancel();
61856171 if (windows.kernel32.SetConsoleMode(file.handle, console_mode) != 0) return;
61866172 }
6187 if (try isCygwinPty(current_thread, file)) return;
6173 if (try isCygwinPty(file)) return;
61886174 } else {
6189 if (try supportsAnsiEscapeCodes(current_thread, file)) return;
6175 if (try supportsAnsiEscapeCodes(file)) return;
61906176 }
61916177 return error.NotTerminalDevice;
61926178}
61936179
61946180fn fileSupportsAnsiEscapeCodes(userdata: ?*anyopaque, file: File) Io.Cancelable!bool {
61956181 const t: *Threaded = @ptrCast(@alignCast(userdata));
6196 const current_thread = Thread.getCurrent(t);
6197 return supportsAnsiEscapeCodes(current_thread, file);
6182 _ = t;
6183 return supportsAnsiEscapeCodes(file);
61986184}
61996185
6200fn supportsAnsiEscapeCodes(current_thread: *Thread, file: File) Io.Cancelable!bool {
6186fn supportsAnsiEscapeCodes(file: File) Io.Cancelable!bool {
62016187 if (is_windows) {
6202 try current_thread.checkCancel();
6188 try Thread.checkCancel();
62036189 var console_mode: windows.DWORD = 0;
62046190 if (windows.kernel32.GetConsoleMode(file.handle, &console_mode) != 0) {
62056191 if (console_mode & windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0) return true;
62066192 }
6207 return isCygwinPty(current_thread, file);
6193 return isCygwinPty(file);
62086194 }
62096195
62106196 if (native_os == .wasi) {
......@@ -6214,12 +6200,12 @@ fn supportsAnsiEscapeCodes(current_thread: *Thread, file: File) Io.Cancelable!bo
62146200 return false;
62156201 }
62166202
6217 if (try isTty(current_thread, file)) return true;
6203 if (try isTty(file)) return true;
62186204
62196205 return false;
62206206}
62216207
6222fn isCygwinPty(current_thread: *Thread, file: File) Io.Cancelable!bool {
6208fn isCygwinPty(file: File) Io.Cancelable!bool {
62236209 if (!is_windows) return false;
62246210
62256211 const handle = file.handle;
......@@ -6234,7 +6220,7 @@ fn isCygwinPty(current_thread: *Thread, file: File) Io.Cancelable!bool {
62346220 // This allows us to avoid the more costly NtQueryInformationFile call
62356221 // for handles that aren't named pipes.
62366222 {
6237 try current_thread.checkCancel();
6223 try Thread.checkCancel();
62386224 var io_status: windows.IO_STATUS_BLOCK = undefined;
62396225 var device_info: windows.FILE.FS_DEVICE_INFORMATION = undefined;
62406226 const rc = windows.ntdll.NtQueryVolumeInformationFile(
......@@ -6262,7 +6248,7 @@ fn isCygwinPty(current_thread: *Thread, file: File) Io.Cancelable!bool {
62626248 var name_info_bytes align(@alignOf(windows.FILE.NAME_INFORMATION)) = [_]u8{0} ** (name_bytes_offset + num_name_bytes);
62636249
62646250 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
6265 try current_thread.checkCancel();
6251 try Thread.checkCancel();
62666252 const rc = windows.ntdll.NtQueryInformationFile(
62676253 handle,
62686254 &io_status_block,
......@@ -6287,13 +6273,13 @@ fn isCygwinPty(current_thread: *Thread, file: File) Io.Cancelable!bool {
62876273
62886274fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthError!void {
62896275 const t: *Threaded = @ptrCast(@alignCast(userdata));
6290 const current_thread = Thread.getCurrent(t);
6276 _ = t;
62916277
62926278 const signed_len: i64 = @bitCast(length);
62936279 if (signed_len < 0) return error.FileTooBig; // Avoid ambiguous EINVAL errors.
62946280
62956281 if (is_windows) {
6296 try current_thread.checkCancel();
6282 try Thread.checkCancel();
62976283
62986284 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
62996285 const eof_info: windows.FILE.END_OF_FILE_INFORMATION = .{
......@@ -6318,16 +6304,16 @@ fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthE
63186304 }
63196305
63206306 if (native_os == .wasi and !builtin.link_libc) {
6321 try current_thread.beginSyscall();
6307 const syscall: Syscall = try .start();
63226308 while (true) {
63236309 switch (std.os.wasi.fd_filestat_set_size(file.handle, length)) {
6324 .SUCCESS => return current_thread.endSyscall(),
6310 .SUCCESS => return syscall.finish(),
63256311 .INTR => {
6326 try current_thread.checkCancel();
6312 try syscall.checkCancel();
63276313 continue;
63286314 },
63296315 else => |e| {
6330 current_thread.endSyscall();
6316 syscall.finish();
63316317 switch (e) {
63326318 .FBIG => return error.FileTooBig,
63336319 .IO => return error.InputOutput,
......@@ -6343,16 +6329,16 @@ fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthE
63436329 }
63446330 }
63456331
6346 try current_thread.beginSyscall();
6332 const syscall: Syscall = try .start();
63476333 while (true) {
63486334 switch (posix.errno(ftruncate_sym(file.handle, signed_len))) {
6349 .SUCCESS => return current_thread.endSyscall(),
6335 .SUCCESS => return syscall.finish(),
63506336 .INTR => {
6351 try current_thread.checkCancel();
6337 try syscall.checkCancel();
63526338 continue;
63536339 },
63546340 else => |e| {
6355 current_thread.endSyscall();
6341 syscall.finish();
63566342 switch (e) {
63576343 .FBIG => return error.FileTooBig,
63586344 .IO => return error.InputOutput,
......@@ -6370,19 +6356,19 @@ fn fileSetLength(userdata: ?*anyopaque, file: File, length: u64) File.SetLengthE
63706356fn fileSetOwner(userdata: ?*anyopaque, file: File, owner: ?File.Uid, group: ?File.Gid) File.SetOwnerError!void {
63716357 if (!have_fchown) return error.Unexpected; // Unsupported OS, don't call this function.
63726358 const t: *Threaded = @ptrCast(@alignCast(userdata));
6373 const current_thread = Thread.getCurrent(t);
6359 _ = t;
63746360 const uid = owner orelse ~@as(posix.uid_t, 0);
63756361 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);
63776363}
63786364
63796365fn fileSetPermissions(userdata: ?*anyopaque, file: File, permissions: File.Permissions) File.SetPermissionsError!void {
63806366 if (@sizeOf(File.Permissions) == 0) return;
63816367 const t: *Threaded = @ptrCast(@alignCast(userdata));
6382 const current_thread = Thread.getCurrent(t);
6368 _ = t;
63836369 switch (native_os) {
63846370 .windows => {
6385 try current_thread.checkCancel();
6371 try Thread.checkCancel();
63866372 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
63876373 const info: windows.FILE.BASIC_INFORMATION = .{
63886374 .CreationTime = 0,
......@@ -6406,22 +6392,22 @@ fn fileSetPermissions(userdata: ?*anyopaque, file: File, permissions: File.Permi
64066392 }
64076393 },
64086394 .wasi => return error.Unexpected, // Unsupported OS.
6409 else => return setPermissionsPosix(current_thread, file.handle, permissions.toMode()),
6395 else => return setPermissionsPosix(file.handle, permissions.toMode()),
64106396 }
64116397}
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 {
64146400 comptime assert(have_fchmod);
6415 try current_thread.beginSyscall();
6401 const syscall: Syscall = try .start();
64166402 while (true) {
64176403 switch (posix.errno(posix.system.fchmod(fd, mode))) {
6418 .SUCCESS => return current_thread.endSyscall(),
6404 .SUCCESS => return syscall.finish(),
64196405 .INTR => {
6420 try current_thread.checkCancel();
6406 try syscall.checkCancel();
64216407 continue;
64226408 },
64236409 else => |e| {
6424 current_thread.endSyscall();
6410 syscall.finish();
64256411 switch (e) {
64266412 .BADF => |err| return errnoBug(err),
64276413 .FAULT => |err| return errnoBug(err),
......@@ -6448,7 +6434,7 @@ fn dirSetTimestamps(
64486434 options: Dir.SetTimestampsOptions,
64496435) Dir.SetTimestampsError!void {
64506436 const t: *Threaded = @ptrCast(@alignCast(userdata));
6451 const current_thread = Thread.getCurrent(t);
6437 _ = t;
64526438
64536439 if (is_windows) {
64546440 @panic("TODO implement dirSetTimestamps windows");
......@@ -6472,20 +6458,20 @@ fn dirSetTimestamps(
64726458 var path_buffer: [posix.PATH_MAX]u8 = undefined;
64736459 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
64746460
6475 try current_thread.beginSyscall();
6461 const syscall: Syscall = try .start();
64766462 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(),
64786464 .INTR => {
6479 try current_thread.checkCancel();
6465 try syscall.checkCancel();
64806466 continue;
64816467 },
6482 .BADF => |err| return current_thread.endSyscallErrnoBug(err), // always a race condition
6483 .FAULT => |err| return current_thread.endSyscallErrnoBug(err),
6484 .INVAL => |err| return current_thread.endSyscallErrnoBug(err),
6485 .ACCES => return current_thread.endSyscallError(error.AccessDenied),
6486 .PERM => return current_thread.endSyscallError(error.PermissionDenied),
6487 .ROFS => return current_thread.endSyscallError(error.ReadOnlyFileSystem),
6488 else => |err| return current_thread.endSyscallUnexpectedErrno(err),
6468 .BADF => |err| return syscall.errnoBug(err), // always a race condition
6469 .FAULT => |err| return syscall.errnoBug(err),
6470 .INVAL => |err| return syscall.errnoBug(err),
6471 .ACCES => return syscall.fail(error.AccessDenied),
6472 .PERM => return syscall.fail(error.PermissionDenied),
6473 .ROFS => return syscall.fail(error.ReadOnlyFileSystem),
6474 else => |err| return syscall.unexpectedErrno(err),
64896475 };
64906476}
64916477
......@@ -6495,10 +6481,10 @@ fn fileSetTimestamps(
64956481 options: File.SetTimestampsOptions,
64966482) File.SetTimestampsError!void {
64976483 const t: *Threaded = @ptrCast(@alignCast(userdata));
6498 const current_thread = Thread.getCurrent(t);
6484 _ = t;
64996485
65006486 if (is_windows) {
6501 try current_thread.checkCancel();
6487 try Thread.checkCancel();
65026488
65036489 var access_time_buffer: windows.FILETIME = undefined;
65046490 var modify_time_buffer: windows.FILETIME = undefined;
......@@ -6559,20 +6545,20 @@ fn fileSetTimestamps(
65596545 },
65606546 }
65616547
6562 try current_thread.beginSyscall();
6548 const syscall: Syscall = try .start();
65636549 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(),
65656551 .INTR => {
6566 try current_thread.checkCancel();
6552 try syscall.checkCancel();
65676553 continue;
65686554 },
6569 .BADF => |err| return current_thread.endSyscallErrnoBug(err), // File descriptor use-after-free.
6570 .FAULT => |err| return current_thread.endSyscallErrnoBug(err),
6571 .INVAL => |err| return current_thread.endSyscallErrnoBug(err),
6572 .ACCES => return current_thread.endSyscallError(error.AccessDenied),
6573 .PERM => return current_thread.endSyscallError(error.PermissionDenied),
6574 .ROFS => return current_thread.endSyscallError(error.ReadOnlyFileSystem),
6575 else => |err| return current_thread.endSyscallUnexpectedErrno(err),
6555 .BADF => |err| return syscall.errnoBug(err), // File descriptor use-after-free.
6556 .FAULT => |err| return syscall.errnoBug(err),
6557 .INVAL => |err| return syscall.errnoBug(err),
6558 .ACCES => return syscall.fail(error.AccessDenied),
6559 .PERM => return syscall.fail(error.PermissionDenied),
6560 .ROFS => return syscall.fail(error.ReadOnlyFileSystem),
6561 else => |err| return syscall.unexpectedErrno(err),
65766562 };
65776563 }
65786564
......@@ -6585,20 +6571,20 @@ fn fileSetTimestamps(
65856571 break :p &times_buffer;
65866572 };
65876573
6588 try current_thread.beginSyscall();
6574 const syscall: Syscall = try .start();
65896575 while (true) switch (posix.errno(posix.system.futimens(file.handle, times))) {
6590 .SUCCESS => return current_thread.endSyscall(),
6576 .SUCCESS => return syscall.finish(),
65916577 .INTR => {
6592 try current_thread.checkCancel();
6578 try syscall.checkCancel();
65936579 continue;
65946580 },
6595 .BADF => |err| return current_thread.endSyscallErrnoBug(err), // always a race condition
6596 .FAULT => |err| return current_thread.endSyscallErrnoBug(err),
6597 .INVAL => |err| return current_thread.endSyscallErrnoBug(err),
6598 .ACCES => return current_thread.endSyscallError(error.AccessDenied),
6599 .PERM => return current_thread.endSyscallError(error.PermissionDenied),
6600 .ROFS => return current_thread.endSyscallError(error.ReadOnlyFileSystem),
6601 else => |err| return current_thread.endSyscallUnexpectedErrno(err),
6581 .BADF => |err| return syscall.errnoBug(err), // always a race condition
6582 .FAULT => |err| return syscall.errnoBug(err),
6583 .INVAL => |err| return syscall.errnoBug(err),
6584 .ACCES => return syscall.fail(error.AccessDenied),
6585 .PERM => return syscall.fail(error.PermissionDenied),
6586 .ROFS => return syscall.fail(error.ReadOnlyFileSystem),
6587 else => |err| return syscall.unexpectedErrno(err),
66026588 };
66036589}
66046590
......@@ -6608,7 +6594,7 @@ const windows_lock_range_len: windows.LARGE_INTEGER = 1;
66086594fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!void {
66096595 if (native_os == .wasi) return error.FileLocksUnsupported;
66106596 const t: *Threaded = @ptrCast(@alignCast(userdata));
6611 const current_thread = Thread.getCurrent(t);
6597 _ = t;
66126598
66136599 if (is_windows) {
66146600 const exclusive = switch (lock) {
......@@ -6633,7 +6619,7 @@ fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!v
66336619 .shared => false,
66346620 .exclusive => true,
66356621 };
6636 try current_thread.checkCancel();
6622 try Thread.checkCancel();
66376623 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
66386624 const status = windows.ntdll.NtLockFile(
66396625 file.handle,
......@@ -6661,16 +6647,16 @@ fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!v
66616647 .shared => posix.LOCK.SH,
66626648 .exclusive => posix.LOCK.EX,
66636649 };
6664 try current_thread.beginSyscall();
6650 const syscall: Syscall = try .start();
66656651 while (true) {
66666652 switch (posix.errno(posix.system.flock(file.handle, operation))) {
6667 .SUCCESS => return current_thread.endSyscall(),
6653 .SUCCESS => return syscall.finish(),
66686654 .INTR => {
6669 try current_thread.checkCancel();
6655 try syscall.checkCancel();
66706656 continue;
66716657 },
66726658 else => |e| {
6673 current_thread.endSyscall();
6659 syscall.finish();
66746660 switch (e) {
66756661 .BADF => |err| return errnoBug(err),
66766662 .INVAL => |err| return errnoBug(err), // invalid parameters
......@@ -6687,7 +6673,7 @@ fn fileLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!v
66876673fn fileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockError!bool {
66886674 if (native_os == .wasi) return error.FileLocksUnsupported;
66896675 const t: *Threaded = @ptrCast(@alignCast(userdata));
6690 const current_thread = Thread.getCurrent(t);
6676 _ = t;
66916677
66926678 if (is_windows) {
66936679 const exclusive = switch (lock) {
......@@ -6711,7 +6697,7 @@ fn fileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockErro
67116697 .shared => false,
67126698 .exclusive => true,
67136699 };
6714 try current_thread.checkCancel();
6700 try Thread.checkCancel();
67156701 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
67166702 const status = windows.ntdll.NtLockFile(
67176703 file.handle,
......@@ -6739,23 +6725,23 @@ fn fileTryLock(userdata: ?*anyopaque, file: File, lock: File.Lock) File.LockErro
67396725 .shared => posix.LOCK.SH | posix.LOCK.NB,
67406726 .exclusive => posix.LOCK.EX | posix.LOCK.NB,
67416727 };
6742 try current_thread.beginSyscall();
6728 const syscall: Syscall = try .start();
67436729 while (true) {
67446730 switch (posix.errno(posix.system.flock(file.handle, operation))) {
67456731 .SUCCESS => {
6746 current_thread.endSyscall();
6732 syscall.finish();
67476733 return true;
67486734 },
67496735 .INTR => {
6750 try current_thread.checkCancel();
6736 try syscall.checkCancel();
67516737 continue;
67526738 },
67536739 .AGAIN => {
6754 current_thread.endSyscall();
6740 syscall.finish();
67556741 return false;
67566742 },
67576743 else => |e| {
6758 current_thread.endSyscall();
6744 syscall.finish();
67596745 switch (e) {
67606746 .BADF => |err| return errnoBug(err),
67616747 .INVAL => |err| return errnoBug(err), // invalid parameters
......@@ -6808,10 +6794,10 @@ fn fileUnlock(userdata: ?*anyopaque, file: File) void {
68086794fn fileDowngradeLock(userdata: ?*anyopaque, file: File) File.DowngradeLockError!void {
68096795 if (native_os == .wasi) return;
68106796 const t: *Threaded = @ptrCast(@alignCast(userdata));
6811 const current_thread = Thread.getCurrent(t);
6797 _ = t;
68126798
68136799 if (is_windows) {
6814 try current_thread.checkCancel();
6800 try Thread.checkCancel();
68156801 // On Windows it works like a semaphore + exclusivity flag. To
68166802 // implement this function, we first obtain another lock in shared
68176803 // mode. This changes the exclusivity flag, but increments the
......@@ -6854,19 +6840,19 @@ fn fileDowngradeLock(userdata: ?*anyopaque, file: File) File.DowngradeLockError!
68546840
68556841 const operation = posix.LOCK.SH | posix.LOCK.NB;
68566842
6857 try current_thread.beginSyscall();
6843 const syscall: Syscall = try .start();
68586844 while (true) {
68596845 switch (posix.errno(posix.system.flock(file.handle, operation))) {
68606846 .SUCCESS => {
6861 current_thread.endSyscall();
6847 syscall.finish();
68626848 return;
68636849 },
68646850 .INTR => {
6865 try current_thread.checkCancel();
6851 try syscall.checkCancel();
68666852 continue;
68676853 },
68686854 else => |e| {
6869 current_thread.endSyscall();
6855 syscall.finish();
68706856 switch (e) {
68716857 .AGAIN => |err| return errnoBug(err), // File was not locked in exclusive mode.
68726858 .BADF => |err| return errnoBug(err),
......@@ -6888,7 +6874,7 @@ fn dirOpenDirWasi(
68886874) Dir.OpenError!Dir {
68896875 if (builtin.link_libc) return dirOpenDirPosix(userdata, dir, sub_path, options);
68906876 const t: *Threaded = @ptrCast(@alignCast(userdata));
6891 const current_thread = Thread.getCurrent(t);
6877 _ = t;
68926878 const wasi = std.os.wasi;
68936879
68946880 var base: std.os.wasi.rights_t = .{
......@@ -6918,19 +6904,19 @@ fn dirOpenDirWasi(
69186904 const oflags: wasi.oflags_t = .{ .DIRECTORY = true };
69196905 const fdflags: wasi.fdflags_t = .{};
69206906 var fd: posix.fd_t = undefined;
6921 try current_thread.beginSyscall();
6907 const syscall: Syscall = try .start();
69226908 while (true) {
69236909 switch (wasi.path_open(dir.handle, lookup_flags, sub_path.ptr, sub_path.len, oflags, base, base, fdflags, &fd)) {
69246910 .SUCCESS => {
6925 current_thread.endSyscall();
6911 syscall.finish();
69266912 return .{ .handle = fd };
69276913 },
69286914 .INTR => {
6929 try current_thread.checkCancel();
6915 try syscall.checkCancel();
69306916 continue;
69316917 },
69326918 else => |e| {
6933 current_thread.endSyscall();
6919 syscall.finish();
69346920 switch (e) {
69356921 .FAULT => |err| return errnoBug(err),
69366922 .INVAL => return error.BadPathName,
......@@ -6965,13 +6951,13 @@ fn dirHardLink(
69656951) Dir.HardLinkError!void {
69666952 if (is_windows) return error.OperationUnsupported;
69676953 const t: *Threaded = @ptrCast(@alignCast(userdata));
6968 const current_thread = Thread.getCurrent(t);
6954 _ = t;
69696955
69706956 if (native_os == .wasi and !builtin.link_libc) {
69716957 const flags: std.os.wasi.lookupflags_t = .{
69726958 .SYMLINK_FOLLOW = options.follow_symlinks,
69736959 };
6974 try current_thread.beginSyscall();
6960 const syscall: Syscall = try .start();
69756961 while (true) {
69766962 switch (std.os.wasi.path_link(
69776963 old_dir.handle,
......@@ -6982,13 +6968,13 @@ fn dirHardLink(
69826968 new_sub_path.ptr,
69836969 new_sub_path.len,
69846970 )) {
6985 .SUCCESS => return current_thread.endSyscall(),
6971 .SUCCESS => return syscall.finish(),
69866972 .INTR => {
6987 try current_thread.checkCancel();
6973 try syscall.checkCancel();
69886974 continue;
69896975 },
69906976 else => |e| {
6991 current_thread.endSyscall();
6977 syscall.finish();
69926978 switch (e) {
69936979 .ACCES => return error.AccessDenied,
69946980 .DQUOT => return error.DiskQuota,
......@@ -7022,7 +7008,7 @@ fn dirHardLink(
70227008
70237009 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();
70267012 while (true) {
70277013 switch (posix.errno(posix.system.linkat(
70287014 old_dir.handle,
......@@ -7031,13 +7017,13 @@ fn dirHardLink(
70317017 new_sub_path_posix,
70327018 flags,
70337019 ))) {
7034 .SUCCESS => return current_thread.endSyscall(),
7020 .SUCCESS => return syscall.finish(),
70357021 .INTR => {
7036 try current_thread.checkCancel();
7022 try syscall.checkCancel();
70377023 continue;
70387024 },
70397025 else => |e| {
7040 current_thread.endSyscall();
7026 syscall.finish();
70417027 switch (e) {
70427028 .ACCES => return error.AccessDenied,
70437029 .DQUOT => return error.DiskQuota,
......@@ -7076,7 +7062,7 @@ const fileReadStreaming = switch (native_os) {
70767062
70777063fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8) File.Reader.Error!usize {
70787064 const t: *Threaded = @ptrCast(@alignCast(userdata));
7079 const current_thread = Thread.getCurrent(t);
7065 _ = t;
70807066
70817067 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;
70827068 var i: usize = 0;
......@@ -7092,20 +7078,20 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)
70927078 assert(dest[0].len > 0);
70937079
70947080 if (native_os == .wasi and !builtin.link_libc) {
7095 try current_thread.beginSyscall();
7081 const syscall: Syscall = try .start();
70967082 while (true) {
70977083 var nread: usize = undefined;
70987084 switch (std.os.wasi.fd_read(file.handle, dest.ptr, dest.len, &nread)) {
70997085 .SUCCESS => {
7100 current_thread.endSyscall();
7086 syscall.finish();
71017087 return nread;
71027088 },
71037089 .INTR => {
7104 try current_thread.checkCancel();
7090 try syscall.checkCancel();
71057091 continue;
71067092 },
71077093 else => |e| {
7108 current_thread.endSyscall();
7094 syscall.finish();
71097095 switch (e) {
71107096 .INVAL => |err| return errnoBug(err),
71117097 .FAULT => |err| return errnoBug(err),
......@@ -7125,20 +7111,20 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)
71257111 }
71267112 }
71277113
7128 try current_thread.beginSyscall();
7114 const syscall: Syscall = try .start();
71297115 while (true) {
71307116 const rc = posix.system.readv(file.handle, dest.ptr, @intCast(dest.len));
71317117 switch (posix.errno(rc)) {
71327118 .SUCCESS => {
7133 current_thread.endSyscall();
7119 syscall.finish();
71347120 return @intCast(rc);
71357121 },
71367122 .INTR => {
7137 try current_thread.checkCancel();
7123 try syscall.checkCancel();
71387124 continue;
71397125 },
71407126 else => |e| {
7141 current_thread.endSyscall();
7127 syscall.finish();
71427128 switch (e) {
71437129 .INVAL => |err| return errnoBug(err),
71447130 .FAULT => |err| return errnoBug(err),
......@@ -7163,7 +7149,7 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8)
71637149
71647150fn fileReadStreamingWindows(userdata: ?*anyopaque, file: File, data: []const []u8) File.Reader.Error!usize {
71657151 const t: *Threaded = @ptrCast(@alignCast(userdata));
7166 const current_thread = Thread.getCurrent(t);
7152 _ = t;
71677153
71687154 const DWORD = windows.DWORD;
71697155 var index: usize = 0;
......@@ -7173,7 +7159,7 @@ fn fileReadStreamingWindows(userdata: ?*anyopaque, file: File, data: []const []u
71737159 const want_read_count: DWORD = @min(std.math.maxInt(DWORD), buffer.len);
71747160
71757161 while (true) {
7176 try current_thread.checkCancel();
7162 try Thread.checkCancel();
71777163 var n: DWORD = undefined;
71787164 if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, null) != 0)
71797165 return n;
......@@ -7193,7 +7179,7 @@ fn fileReadStreamingWindows(userdata: ?*anyopaque, file: File, data: []const []u
71937179
71947180fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8, offset: u64) File.ReadPositionalError!usize {
71957181 const t: *Threaded = @ptrCast(@alignCast(userdata));
7196 const current_thread = Thread.getCurrent(t);
7182 _ = t;
71977183
71987184 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
72117197 assert(dest[0].len > 0);
72127198
72137199 if (native_os == .wasi and !builtin.link_libc) {
7214 try current_thread.beginSyscall();
7200 const syscall: Syscall = try .start();
72157201 while (true) {
72167202 var nread: usize = undefined;
72177203 switch (std.os.wasi.fd_pread(file.handle, dest.ptr, dest.len, offset, &nread)) {
72187204 .SUCCESS => {
7219 current_thread.endSyscall();
7205 syscall.finish();
72207206 return nread;
72217207 },
72227208 .INTR => {
7223 try current_thread.checkCancel();
7209 try syscall.checkCancel();
72247210 continue;
72257211 },
72267212 else => |e| {
7227 current_thread.endSyscall();
7213 syscall.finish();
72287214 switch (e) {
72297215 .INVAL => |err| return errnoBug(err),
72307216 .FAULT => |err| return errnoBug(err),
......@@ -7248,20 +7234,20 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8
72487234 }
72497235 }
72507236
7251 try current_thread.beginSyscall();
7237 const syscall: Syscall = try .start();
72527238 while (true) {
72537239 const rc = preadv_sym(file.handle, dest.ptr, @intCast(dest.len), @bitCast(offset));
72547240 switch (posix.errno(rc)) {
72557241 .SUCCESS => {
7256 current_thread.endSyscall();
7242 syscall.finish();
72577243 return @bitCast(rc);
72587244 },
72597245 .INTR => {
7260 try current_thread.checkCancel();
7246 try syscall.checkCancel();
72617247 continue;
72627248 },
72637249 else => |e| {
7264 current_thread.endSyscall();
7250 syscall.finish();
72657251 switch (e) {
72667252 .INVAL => |err| return errnoBug(err),
72677253 .FAULT => |err| return errnoBug(err),
......@@ -7294,7 +7280,7 @@ const fileReadPositional = switch (native_os) {
72947280
72957281fn fileReadPositionalWindows(userdata: ?*anyopaque, file: File, data: []const []u8, offset: u64) File.ReadPositionalError!usize {
72967282 const t: *Threaded = @ptrCast(@alignCast(userdata));
7297 const current_thread = Thread.getCurrent(t);
7283 _ = t;
72987284
72997285 const DWORD = windows.DWORD;
73007286
......@@ -7317,7 +7303,7 @@ fn fileReadPositionalWindows(userdata: ?*anyopaque, file: File, data: []const []
73177303 };
73187304
73197305 while (true) {
7320 try current_thread.checkCancel();
7306 try Thread.checkCancel();
73217307 var n: DWORD = undefined;
73227308 if (windows.kernel32.ReadFile(file.handle, buffer.ptr, want_read_count, &n, &overlapped) != 0)
73237309 return n;
......@@ -7337,24 +7323,24 @@ fn fileReadPositionalWindows(userdata: ?*anyopaque, file: File, data: []const []
73377323
73387324fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!void {
73397325 const t: *Threaded = @ptrCast(@alignCast(userdata));
7340 const current_thread = Thread.getCurrent(t);
7326 _ = t;
73417327 const fd = file.handle;
73427328
73437329 if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
73447330 var result: u64 = undefined;
7345 try current_thread.beginSyscall();
7331 const syscall: Syscall = try .start();
73467332 while (true) {
73477333 switch (posix.errno(posix.system.llseek(fd, @bitCast(offset), &result, posix.SEEK.CUR))) {
73487334 .SUCCESS => {
7349 current_thread.endSyscall();
7335 syscall.finish();
73507336 return;
73517337 },
73527338 .INTR => {
7353 try current_thread.checkCancel();
7339 try syscall.checkCancel();
73547340 continue;
73557341 },
73567342 else => |e| {
7357 current_thread.endSyscall();
7343 syscall.finish();
73587344 switch (e) {
73597345 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
73607346 .INVAL => return error.Unseekable,
......@@ -7369,25 +7355,25 @@ fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!voi
73697355 }
73707356
73717357 if (native_os == .windows) {
7372 try current_thread.checkCancel();
7358 try Thread.checkCancel();
73737359 return windows.SetFilePointerEx_CURRENT(fd, offset);
73747360 }
73757361
73767362 if (native_os == .wasi and !builtin.link_libc) {
73777363 var new_offset: std.os.wasi.filesize_t = undefined;
7378 try current_thread.beginSyscall();
7364 const syscall: Syscall = try .start();
73797365 while (true) {
73807366 switch (std.os.wasi.fd_seek(fd, offset, .CUR, &new_offset)) {
73817367 .SUCCESS => {
7382 current_thread.endSyscall();
7368 syscall.finish();
73837369 return;
73847370 },
73857371 .INTR => {
7386 try current_thread.checkCancel();
7372 try syscall.checkCancel();
73877373 continue;
73887374 },
73897375 else => |e| {
7390 current_thread.endSyscall();
7376 syscall.finish();
73917377 switch (e) {
73927378 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
73937379 .INVAL => return error.Unseekable,
......@@ -7404,19 +7390,19 @@ fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!voi
74047390
74057391 if (posix.SEEK == void) return error.Unseekable;
74067392
7407 try current_thread.beginSyscall();
7393 const syscall: Syscall = try .start();
74087394 while (true) {
74097395 switch (posix.errno(lseek_sym(fd, offset, posix.SEEK.CUR))) {
74107396 .SUCCESS => {
7411 current_thread.endSyscall();
7397 syscall.finish();
74127398 return;
74137399 },
74147400 .INTR => {
7415 try current_thread.checkCancel();
7401 try syscall.checkCancel();
74167402 continue;
74177403 },
74187404 else => |e| {
7419 current_thread.endSyscall();
7405 syscall.finish();
74207406 switch (e) {
74217407 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
74227408 .INVAL => return error.Unseekable,
......@@ -7432,29 +7418,29 @@ fn fileSeekBy(userdata: ?*anyopaque, file: File, offset: i64) File.SeekError!voi
74327418
74337419fn fileSeekTo(userdata: ?*anyopaque, file: File, offset: u64) File.SeekError!void {
74347420 const t: *Threaded = @ptrCast(@alignCast(userdata));
7435 const current_thread = Thread.getCurrent(t);
7421 _ = t;
74367422 const fd = file.handle;
74377423
74387424 if (native_os == .windows) {
7439 try current_thread.checkCancel();
7425 try Thread.checkCancel();
74407426 return windows.SetFilePointerEx_BEGIN(fd, offset);
74417427 }
74427428
74437429 if (native_os == .wasi and !builtin.link_libc) {
7444 try current_thread.beginSyscall();
7430 const syscall: Syscall = try .start();
74457431 while (true) {
74467432 var new_offset: std.os.wasi.filesize_t = undefined;
74477433 switch (std.os.wasi.fd_seek(fd, @bitCast(offset), .SET, &new_offset)) {
74487434 .SUCCESS => {
7449 current_thread.endSyscall();
7435 syscall.finish();
74507436 return;
74517437 },
74527438 .INTR => {
7453 try current_thread.checkCancel();
7439 try syscall.checkCancel();
74547440 continue;
74557441 },
74567442 else => |e| {
7457 current_thread.endSyscall();
7443 syscall.finish();
74587444 switch (e) {
74597445 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
74607446 .INVAL => return error.Unseekable,
......@@ -7471,25 +7457,25 @@ fn fileSeekTo(userdata: ?*anyopaque, file: File, offset: u64) File.SeekError!voi
74717457
74727458 if (posix.SEEK == void) return error.Unseekable;
74737459
7474 return posixSeekTo(current_thread, fd, offset);
7460 return posixSeekTo(fd, offset);
74757461}
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 {
74787464 if (native_os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
7479 try current_thread.beginSyscall();
7465 const syscall: Syscall = try .start();
74807466 while (true) {
74817467 var result: u64 = undefined;
74827468 switch (posix.errno(posix.system.llseek(fd, offset, &result, posix.SEEK.SET))) {
74837469 .SUCCESS => {
7484 current_thread.endSyscall();
7470 syscall.finish();
74857471 return;
74867472 },
74877473 .INTR => {
7488 try current_thread.checkCancel();
7474 try syscall.checkCancel();
74897475 continue;
74907476 },
74917477 else => |e| {
7492 current_thread.endSyscall();
7478 syscall.finish();
74937479 switch (e) {
74947480 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
74957481 .INVAL => return error.Unseekable,
......@@ -7503,19 +7489,19 @@ fn posixSeekTo(current_thread: *Thread, fd: posix.fd_t, offset: u64) File.SeekEr
75037489 }
75047490 }
75057491
7506 try current_thread.beginSyscall();
7492 const syscall: Syscall = try .start();
75077493 while (true) {
75087494 switch (posix.errno(lseek_sym(fd, @bitCast(offset), posix.SEEK.SET))) {
75097495 .SUCCESS => {
7510 current_thread.endSyscall();
7496 syscall.finish();
75117497 return;
75127498 },
75137499 .INTR => {
7514 try current_thread.checkCancel();
7500 try syscall.checkCancel();
75157501 continue;
75167502 },
75177503 else => |e| {
7518 current_thread.endSyscall();
7504 syscall.finish();
75197505 switch (e) {
75207506 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
75217507 .INVAL => return error.Unseekable,
......@@ -7605,22 +7591,21 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
76057591 else => |e| return e,
76067592 },
76077593 .freebsd, .dragonfly => {
7608 const current_thread = Thread.getCurrent(t);
76097594 var mib: [4]c_int = .{ posix.CTL.KERN, posix.KERN.PROC, posix.KERN.PROC_PATHNAME, -1 };
76107595 var out_len: usize = out_buffer.len;
7611 try current_thread.beginSyscall();
7596 const syscall: Syscall = try .start();
76127597 while (true) {
76137598 switch (posix.errno(posix.system.sysctl(&mib, mib.len, out_buffer.ptr, &out_len, null, 0))) {
76147599 .SUCCESS => {
7615 current_thread.endSyscall();
7600 syscall.finish();
76167601 return out_len - 1; // discard terminating NUL
76177602 },
76187603 .INTR => {
7619 try current_thread.checkCancel();
7604 try syscall.checkCancel();
76207605 continue;
76217606 },
76227607 else => |e| {
7623 current_thread.endSyscall();
7608 syscall.finish();
76247609 switch (e) {
76257610 .FAULT => |err| return errnoBug(err),
76267611 .PERM => return error.PermissionDenied,
......@@ -7633,22 +7618,21 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
76337618 }
76347619 },
76357620 .netbsd => {
7636 const current_thread = Thread.getCurrent(t);
76377621 var mib = [4]c_int{ posix.CTL.KERN, posix.KERN.PROC_ARGS, -1, posix.KERN.PROC_PATHNAME };
76387622 var out_len: usize = out_buffer.len;
7639 try current_thread.beginSyscall();
7623 const syscall: Syscall = try .start();
76407624 while (true) {
76417625 switch (posix.errno(posix.system.sysctl(&mib, mib.len, out_buffer.ptr, &out_len, null, 0))) {
76427626 .SUCCESS => {
7643 current_thread.endSyscall();
7627 syscall.finish();
76447628 return out_len - 1; // discard terminating NUL
76457629 },
76467630 .INTR => {
7647 try current_thread.checkCancel();
7631 try syscall.checkCancel();
76487632 continue;
76497633 },
76507634 else => |e| {
7651 current_thread.endSyscall();
7635 syscall.finish();
76527636 switch (e) {
76537637 .FAULT => |err| return errnoBug(err),
76547638 .PERM => return error.PermissionDenied,
......@@ -7666,20 +7650,19 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
76667650 const argv0 = std.mem.span(t.argv0.value orelse return error.OperationUnsupported);
76677651 if (std.mem.findScalar(u8, argv0, '/') != null) {
76687652 // argv[0] is a path (relative or absolute): use realpath(3) directly
7669 const current_thread = Thread.getCurrent(t);
76707653 var resolved_buf: [std.c.PATH_MAX]u8 = undefined;
7671 try current_thread.beginSyscall();
7654 const syscall: Syscall = try .start();
76727655 while (true) {
76737656 if (std.c.realpath(argv0, &resolved_buf)) |p| {
76747657 assert(p == &resolved_buf);
7675 break current_thread.endSyscall();
7658 break syscall.finish();
76767659 } else switch (@as(std.c.E, @enumFromInt(std.c._errno().*))) {
76777660 .INTR => {
7678 try current_thread.checkCancel();
7661 try syscall.checkCancel();
76797662 continue;
76807663 },
76817664 else => |e| {
7682 current_thread.endSyscall();
7665 syscall.finish();
76837666 switch (e) {
76847667 .ACCES => return error.AccessDenied,
76857668 .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
77037686 // argv[0] is not empty (and not a path): search PATH
77047687 t.scanEnviron();
77057688 const PATH = t.environ.string.PATH orelse return error.FileNotFound;
7706 const current_thread = Thread.getCurrent(t);
77077689 var it = std.mem.tokenizeScalar(u8, PATH, ':');
77087690 it: while (it.next()) |dir| {
77097691 var resolved_path_buf: [std.c.PATH_MAX]u8 = undefined;
......@@ -7712,34 +7694,34 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
77127694 }, 0) catch continue;
77137695
77147696 var resolved_buf: [std.c.PATH_MAX]u8 = undefined;
7715 try current_thread.beginSyscall();
7697 const syscall: Syscall = try .start();
77167698 while (true) {
77177699 if (std.c.realpath(resolved_path, &resolved_buf)) |p| {
77187700 assert(p == &resolved_buf);
7719 break current_thread.endSyscall();
7701 break syscall.finish();
77207702 } else switch (@as(std.c.E, @enumFromInt(std.c._errno().*))) {
77217703 .INTR => {
7722 try current_thread.checkCancel();
7704 try syscall.checkCancel();
77237705 continue;
77247706 },
77257707 .NAMETOOLONG => {
7726 current_thread.endSyscall();
7708 syscall.finish();
77277709 return error.NameTooLong;
77287710 },
77297711 .NOMEM => {
7730 current_thread.endSyscall();
7712 syscall.finish();
77317713 return error.SystemResources;
77327714 },
77337715 .IO => {
7734 current_thread.endSyscall();
7716 syscall.finish();
77357717 return error.InputOutput;
77367718 },
77377719 .ACCES, .LOOP, .NOENT, .NOTDIR => {
7738 current_thread.endSyscall();
7720 syscall.finish();
77397721 continue :it;
77407722 },
77417723 else => |err| {
7742 current_thread.endSyscall();
7724 syscall.finish();
77437725 return posix.unexpectedErrno(err);
77447726 },
77457727 }
......@@ -7754,8 +7736,7 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
77547736 return error.FileNotFound;
77557737 },
77567738 .windows => {
7757 const current_thread = Thread.getCurrent(t);
7758 try current_thread.checkCancel();
7739 try Thread.checkCancel();
77597740 const w = windows;
77607741 const image_path_unicode_string = &w.peb().ProcessParameters.ImagePathName;
77617742 const image_path_name = image_path_unicode_string.Buffer.?[0 .. image_path_unicode_string.Length / 2 :0];
......@@ -7805,19 +7786,19 @@ fn fileWritePositional(
78057786 offset: u64,
78067787) File.WritePositionalError!usize {
78077788 const t: *Threaded = @ptrCast(@alignCast(userdata));
7808 const current_thread = Thread.getCurrent(t);
7789 _ = t;
78097790
78107791 if (is_windows) {
78117792 if (header.len != 0) {
7812 return writeFilePositionalWindows(current_thread, file.handle, header, offset);
7793 return writeFilePositionalWindows(file.handle, header, offset);
78137794 }
78147795 for (data[0 .. data.len - 1]) |buf| {
78157796 if (buf.len == 0) continue;
7816 return writeFilePositionalWindows(current_thread, file.handle, buf, offset);
7797 return writeFilePositionalWindows(file.handle, buf, offset);
78177798 }
78187799 const pattern = data[data.len - 1];
78197800 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);
78217802 }
78227803
78237804 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;
......@@ -7855,19 +7836,19 @@ fn fileWritePositional(
78557836
78567837 if (native_os == .wasi and !builtin.link_libc) {
78577838 var n_written: usize = undefined;
7858 try current_thread.beginSyscall();
7839 const syscall: Syscall = try .start();
78597840 while (true) {
78607841 switch (std.os.wasi.fd_pwrite(file.handle, &iovecs, iovlen, offset, &n_written)) {
78617842 .SUCCESS => {
7862 current_thread.endSyscall();
7843 syscall.finish();
78637844 return n_written;
78647845 },
78657846 .INTR => {
7866 try current_thread.checkCancel();
7847 try syscall.checkCancel();
78677848 continue;
78687849 },
78697850 else => |e| {
7870 current_thread.endSyscall();
7851 syscall.finish();
78717852 switch (e) {
78727853 .INVAL => |err| return errnoBug(err),
78737854 .FAULT => |err| return errnoBug(err),
......@@ -7891,20 +7872,20 @@ fn fileWritePositional(
78917872 }
78927873 }
78937874
7894 try current_thread.beginSyscall();
7875 const syscall: Syscall = try .start();
78957876 while (true) {
78967877 const rc = pwritev_sym(file.handle, &iovecs, @intCast(iovlen), @bitCast(offset));
78977878 switch (posix.errno(rc)) {
78987879 .SUCCESS => {
7899 current_thread.endSyscall();
7880 syscall.finish();
79007881 return @intCast(rc);
79017882 },
79027883 .INTR => {
7903 try current_thread.checkCancel();
7884 try syscall.checkCancel();
79047885 continue;
79057886 },
79067887 else => |e| {
7907 current_thread.endSyscall();
7888 syscall.finish();
79087889 switch (e) {
79097890 .INVAL => |err| return errnoBug(err),
79107891 .FAULT => |err| return errnoBug(err),
......@@ -7931,12 +7912,11 @@ fn fileWritePositional(
79317912}
79327913
79337914fn writeFilePositionalWindows(
7934 current_thread: *Thread,
79357915 handle: windows.HANDLE,
79367916 bytes: []const u8,
79377917 offset: u64,
79387918) File.WritePositionalError!usize {
7939 try current_thread.checkCancel();
7919 try Thread.checkCancel();
79407920
79417921 var bytes_written: windows.DWORD = undefined;
79427922 var overlapped: windows.OVERLAPPED = .{
......@@ -7976,19 +7956,19 @@ fn fileWriteStreaming(
79767956 splat: usize,
79777957) File.Writer.Error!usize {
79787958 const t: *Threaded = @ptrCast(@alignCast(userdata));
7979 const current_thread = Thread.getCurrent(t);
7959 _ = t;
79807960
79817961 if (is_windows) {
79827962 if (header.len != 0) {
7983 return writeFileStreamingWindows(current_thread, file.handle, header);
7963 return writeFileStreamingWindows(file.handle, header);
79847964 }
79857965 for (data[0 .. data.len - 1]) |buf| {
79867966 if (buf.len == 0) continue;
7987 return writeFileStreamingWindows(current_thread, file.handle, buf);
7967 return writeFileStreamingWindows(file.handle, buf);
79887968 }
79897969 const pattern = data[data.len - 1];
79907970 if (pattern.len == 0 or splat == 0) return 0;
7991 return writeFileStreamingWindows(current_thread, file.handle, pattern);
7971 return writeFileStreamingWindows(file.handle, pattern);
79927972 }
79937973
79947974 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;
......@@ -8026,19 +8006,19 @@ fn fileWriteStreaming(
80268006
80278007 if (native_os == .wasi and !builtin.link_libc) {
80288008 var n_written: usize = undefined;
8029 try current_thread.beginSyscall();
8009 const syscall: Syscall = try .start();
80308010 while (true) {
80318011 switch (std.os.wasi.fd_write(file.handle, &iovecs, iovlen, &n_written)) {
80328012 .SUCCESS => {
8033 current_thread.endSyscall();
8013 syscall.finish();
80348014 return n_written;
80358015 },
80368016 .INTR => {
8037 try current_thread.checkCancel();
8017 try syscall.checkCancel();
80388018 continue;
80398019 },
80408020 else => |e| {
8041 current_thread.endSyscall();
8021 syscall.finish();
80428022 switch (e) {
80438023 .INVAL => |err| return errnoBug(err),
80448024 .FAULT => |err| return errnoBug(err),
......@@ -8059,20 +8039,20 @@ fn fileWriteStreaming(
80598039 }
80608040 }
80618041
8062 try current_thread.beginSyscall();
8042 const syscall: Syscall = try .start();
80638043 while (true) {
80648044 const rc = posix.system.writev(file.handle, &iovecs, @intCast(iovlen));
80658045 switch (posix.errno(rc)) {
80668046 .SUCCESS => {
8067 current_thread.endSyscall();
8047 syscall.finish();
80688048 return @intCast(rc);
80698049 },
80708050 .INTR => {
8071 try current_thread.checkCancel();
8051 try syscall.checkCancel();
80728052 continue;
80738053 },
80748054 else => |e| {
8075 current_thread.endSyscall();
8055 syscall.finish();
80768056 switch (e) {
80778057 .INVAL => |err| return errnoBug(err),
80788058 .FAULT => |err| return errnoBug(err),
......@@ -8095,11 +8075,10 @@ fn fileWriteStreaming(
80958075}
80968076
80978077fn writeFileStreamingWindows(
8098 current_thread: *Thread,
80998078 handle: windows.HANDLE,
81008079 bytes: []const u8,
81018080) File.Writer.Error!usize {
8102 try current_thread.checkCancel();
8081 try Thread.checkCancel();
81038082
81048083 var bytes_written: windows.DWORD = undefined;
81058084 const adjusted_len = std.math.lossyCast(u32, bytes.len);
......@@ -8178,40 +8157,39 @@ fn fileWriteFileStreaming(
81788157 const nbytes: usize = @min(file_limit, std.math.maxInt(usize));
81798158 const flags = 0;
81808159
8181 const current_thread = Thread.getCurrent(t);
8182 try current_thread.beginSyscall();
8160 const syscall: Syscall = try .start();
81838161 while (true) {
81848162 switch (posix.errno(std.c.sendfile(in_fd, out_fd, offset, nbytes, hdtr, &sbytes, flags))) {
81858163 .SUCCESS => {
8186 current_thread.endSyscall();
8164 syscall.finish();
81878165 break;
81888166 },
81898167 .INVAL, .OPNOTSUPP, .NOTSOCK, .NOSYS => {
81908168 // Give calling code chance to observe before trying
81918169 // something else.
8192 current_thread.endSyscall();
8170 syscall.finish();
81938171 @atomicStore(UseSendfile, &t.use_sendfile, .disabled, .monotonic);
81948172 return 0;
81958173 },
81968174 .INTR, .BUSY => {
81978175 if (sbytes == 0) {
8198 try current_thread.checkCancel();
8176 try syscall.checkCancel();
81998177 continue;
82008178 } else {
82018179 // Even if we are being canceled, there have been side
82028180 // effects, so it is better to report those side
82038181 // effects to the caller.
8204 current_thread.endSyscall();
8182 syscall.finish();
82058183 break;
82068184 }
82078185 },
82088186 .AGAIN => {
8209 current_thread.endSyscall();
8187 syscall.finish();
82108188 if (sbytes == 0) return error.WouldBlock;
82118189 break;
82128190 },
82138191 else => |e| {
8214 current_thread.endSyscall();
8192 syscall.finish();
82158193 assert(error.Unexpected == switch (e) {
82168194 .NOTCONN => return error.BrokenPipe,
82178195 .IO => return error.InputOutput,
......@@ -8264,40 +8242,39 @@ fn fileWriteFileStreaming(
82648242 const max_count = std.math.maxInt(i32); // Avoid EINVAL.
82658243 var len: std.c.off_t = @min(file_limit, max_count);
82668244 const flags = 0;
8267 const current_thread = Thread.getCurrent(t);
8268 try current_thread.beginSyscall();
8245 const syscall: Syscall = try .start();
82698246 while (true) {
82708247 switch (posix.errno(std.c.sendfile(in_fd, out_fd, offset, &len, hdtr, flags))) {
82718248 .SUCCESS => {
8272 current_thread.endSyscall();
8249 syscall.finish();
82738250 break;
82748251 },
82758252 .OPNOTSUPP, .NOTSOCK, .NOSYS => {
82768253 // Give calling code chance to observe before trying
82778254 // something else.
8278 current_thread.endSyscall();
8255 syscall.finish();
82798256 @atomicStore(UseSendfile, &t.use_sendfile, .disabled, .monotonic);
82808257 return 0;
82818258 },
82828259 .INTR => {
82838260 if (len == 0) {
8284 try current_thread.checkCancel();
8261 try syscall.checkCancel();
82858262 continue;
82868263 } else {
82878264 // Even if we are being canceled, there have been side
82888265 // effects, so it is better to report those side
82898266 // effects to the caller.
8290 current_thread.endSyscall();
8267 syscall.finish();
82918268 break;
82928269 }
82938270 },
82948271 .AGAIN => {
8295 current_thread.endSyscall();
8272 syscall.finish();
82968273 if (len == 0) return error.WouldBlock;
82978274 break;
82988275 },
82998276 else => |e| {
8300 current_thread.endSyscall();
8277 syscall.finish();
83018278 assert(error.Unexpected == switch (e) {
83028279 .NOTCONN => return error.BrokenPipe,
83038280 .IO => return error.InputOutput,
......@@ -8344,28 +8321,27 @@ fn fileWriteFileStreaming(
83448321 .streaming_simple, .positional_simple => break :sf,
83458322 .failure => return error.ReadFailed,
83468323 };
8347 const current_thread = Thread.getCurrent(t);
8348 try current_thread.beginSyscall();
8324 const syscall: Syscall = try .start();
83498325 const n: usize = while (true) {
83508326 const rc = sendfile_sym(out_fd, in_fd, off_ptr, count);
83518327 switch (posix.errno(rc)) {
83528328 .SUCCESS => {
8353 current_thread.endSyscall();
8329 syscall.finish();
83548330 break @intCast(rc);
83558331 },
83568332 .NOSYS, .INVAL => {
83578333 // Give calling code chance to observe before trying
83588334 // something else.
8359 current_thread.endSyscall();
8335 syscall.finish();
83608336 @atomicStore(UseSendfile, &t.use_sendfile, .disabled, .monotonic);
83618337 return 0;
83628338 },
83638339 .INTR => {
8364 try current_thread.checkCancel();
8340 try syscall.checkCancel();
83658341 continue;
83668342 },
83678343 else => |e| {
8368 current_thread.endSyscall();
8344 syscall.finish();
83698345 assert(error.Unexpected == switch (e) {
83708346 .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket
83718347 .AGAIN => return error.WouldBlock,
......@@ -8421,30 +8397,29 @@ fn fileWriteFileStreaming(
84218397 .streaming => null,
84228398 .failure => return error.ReadFailed,
84238399 };
8424 const current_thread = Thread.getCurrent(t);
84258400 const n: usize = switch (native_os) {
84268401 .linux => n: {
8427 try current_thread.beginSyscall();
8402 const syscall: Syscall = try .start();
84288403 while (true) {
84298404 const rc = linux_copy_file_range_sys.copy_file_range(in_fd, off_in_ptr, out_fd, null, @intFromEnum(limit), 0);
84308405 switch (linux_copy_file_range_sys.errno(rc)) {
84318406 .SUCCESS => {
8432 current_thread.endSyscall();
8407 syscall.finish();
84338408 break :n @intCast(rc);
84348409 },
84358410 .INTR => {
8436 try current_thread.checkCancel();
8411 try syscall.checkCancel();
84378412 continue;
84388413 },
84398414 .OPNOTSUPP, .INVAL, .NOSYS => {
84408415 // Give calling code chance to observe before trying
84418416 // something else.
8442 current_thread.endSyscall();
8417 syscall.finish();
84438418 @atomicStore(UseCopyFileRange, &t.use_copy_file_range, .disabled, .monotonic);
84448419 return 0;
84458420 },
84468421 else => |e| {
8447 current_thread.endSyscall();
8422 syscall.finish();
84488423 assert(error.Unexpected == switch (e) {
84498424 .FBIG => return error.FileTooBig,
84508425 .IO => return error.InputOutput,
......@@ -8468,27 +8443,27 @@ fn fileWriteFileStreaming(
84688443 }
84698444 },
84708445 .freebsd => n: {
8471 try current_thread.beginSyscall();
8446 const syscall: Syscall = try .start();
84728447 while (true) {
84738448 const rc = std.c.copy_file_range(in_fd, off_in_ptr, out_fd, null, @intFromEnum(limit), 0);
84748449 switch (std.c.errno(rc)) {
84758450 .SUCCESS => {
8476 current_thread.endSyscall();
8451 syscall.finish();
84778452 break :n @intCast(rc);
84788453 },
84798454 .INTR => {
8480 try current_thread.checkCancel();
8455 try syscall.checkCancel();
84818456 continue;
84828457 },
84838458 .OPNOTSUPP, .INVAL, .NOSYS => {
84848459 // Give calling code chance to observe before trying
84858460 // something else.
8486 current_thread.endSyscall();
8461 syscall.finish();
84878462 @atomicStore(UseCopyFileRange, &t.use_copy_file_range, .disabled, .monotonic);
84888463 return 0;
84898464 },
84908465 else => |e| {
8491 current_thread.endSyscall();
8466 syscall.finish();
84928467 assert(error.Unexpected == switch (e) {
84938468 .FBIG => return error.FileTooBig,
84948469 .IO => return error.InputOutput,
......@@ -8597,30 +8572,29 @@ fn fileWriteFilePositional(
85978572 .failure => return error.ReadFailed,
85988573 };
85998574 var off_out: i64 = @intCast(offset);
8600 const current_thread = Thread.getCurrent(t);
86018575 const n: usize = switch (native_os) {
86028576 .linux => n: {
8603 try current_thread.beginSyscall();
8577 const syscall: Syscall = try .start();
86048578 while (true) {
86058579 const rc = linux_copy_file_range_sys.copy_file_range(in_fd, off_in_ptr, out_fd, &off_out, @intFromEnum(limit), 0);
86068580 switch (linux_copy_file_range_sys.errno(rc)) {
86078581 .SUCCESS => {
8608 current_thread.endSyscall();
8582 syscall.finish();
86098583 break :n @intCast(rc);
86108584 },
86118585 .INTR => {
8612 try current_thread.checkCancel();
8586 try syscall.checkCancel();
86138587 continue;
86148588 },
86158589 .OPNOTSUPP, .INVAL, .NOSYS => {
86168590 // Give calling code chance to observe before trying
86178591 // something else.
8618 current_thread.endSyscall();
8592 syscall.finish();
86198593 @atomicStore(UseCopyFileRange, &t.use_copy_file_range, .disabled, .monotonic);
86208594 return 0;
86218595 },
86228596 else => |e| {
8623 current_thread.endSyscall();
8597 syscall.finish();
86248598 assert(error.Unexpected == switch (e) {
86258599 .FBIG => return error.FileTooBig,
86268600 .IO => return error.InputOutput,
......@@ -8645,27 +8619,27 @@ fn fileWriteFilePositional(
86458619 }
86468620 },
86478621 .freebsd => n: {
8648 try current_thread.beginSyscall();
8622 const syscall: Syscall = try .start();
86498623 while (true) {
86508624 const rc = std.c.copy_file_range(in_fd, off_in_ptr, out_fd, &off_out, @intFromEnum(limit), 0);
86518625 switch (std.c.errno(rc)) {
86528626 .SUCCESS => {
8653 current_thread.endSyscall();
8627 syscall.finish();
86548628 break :n @intCast(rc);
86558629 },
86568630 .INTR => {
8657 try current_thread.checkCancel();
8631 try syscall.checkCancel();
86588632 continue;
86598633 },
86608634 .OPNOTSUPP, .INVAL, .NOSYS => {
86618635 // Give calling code chance to observe before trying
86628636 // something else.
8663 current_thread.endSyscall();
8637 syscall.finish();
86648638 @atomicStore(UseCopyFileRange, &t.use_copy_file_range, .disabled, .monotonic);
86658639 return 0;
86668640 },
86678641 else => |e| {
8668 current_thread.endSyscall();
8642 syscall.finish();
86698643 assert(error.Unexpected == switch (e) {
86708644 .FBIG => return error.FileTooBig,
86718645 .IO => return error.InputOutput,
......@@ -8705,28 +8679,27 @@ fn fileWriteFilePositional(
87058679 file_reader.interface.toss(n -| header.len);
87068680 return n;
87078681 }
8708 const current_thread = Thread.getCurrent(t);
8709 try current_thread.beginSyscall();
8682 const syscall: Syscall = try .start();
87108683 while (true) {
87118684 const rc = std.c.fcopyfile(in_fd, out_fd, null, .{ .DATA = true });
87128685 switch (posix.errno(rc)) {
87138686 .SUCCESS => {
8714 current_thread.endSyscall();
8687 syscall.finish();
87158688 break;
87168689 },
87178690 .INTR => {
8718 try current_thread.checkCancel();
8691 try syscall.checkCancel();
87198692 continue;
87208693 },
87218694 .OPNOTSUPP => {
87228695 // Give calling code chance to observe before trying
87238696 // something else.
8724 current_thread.endSyscall();
8697 syscall.finish();
87258698 @atomicStore(UseFcopyfile, &t.use_fcopyfile, .disabled, .monotonic);
87268699 return 0;
87278700 },
87288701 else => |e| {
8729 current_thread.endSyscall();
8702 syscall.finish();
87308703 assert(error.Unexpected == switch (e) {
87318704 .NOMEM => return error.SystemResources,
87328705 .INVAL => |err| errnoBug(err),
......@@ -8814,7 +8787,7 @@ const sleep = switch (native_os) {
88148787
88158788fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
88168789 const t: *Threaded = @ptrCast(@alignCast(userdata));
8817 const current_thread = Thread.getCurrent(t);
8790 _ = t;
88188791 const clock_id: posix.clockid_t = clockToPosix(switch (timeout) {
88198792 .none => .awake,
88208793 .duration => |d| d.clock,
......@@ -8826,22 +8799,22 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
88268799 .deadline => |deadline| deadline.raw.nanoseconds,
88278800 };
88288801 var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);
8829 try current_thread.beginSyscall();
8802 const syscall: Syscall = try .start();
88308803 while (true) {
88318804 switch (std.os.linux.errno(std.os.linux.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {
88328805 .none, .duration => false,
88338806 .deadline => true,
88348807 } }, &timespec, &timespec))) {
88358808 .SUCCESS => {
8836 current_thread.endSyscall();
8809 syscall.finish();
88378810 return;
88388811 },
88398812 .INTR => {
8840 try current_thread.checkCancel();
8813 try syscall.checkCancel();
88418814 continue;
88428815 },
88438816 else => |e| {
8844 current_thread.endSyscall();
8817 syscall.finish();
88458818 switch (e) {
88468819 .INVAL => return error.UnsupportedClock,
88478820 else => |err| return posix.unexpectedErrno(err),
......@@ -8853,9 +8826,8 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
88538826
88548827fn sleepWindows(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
88558828 const t: *Threaded = @ptrCast(@alignCast(userdata));
8856 const current_thread = Thread.getCurrent(t);
88578829 const t_io = ioBasic(t);
8858 try current_thread.checkCancel();
8830 try Thread.checkCancel();
88598831 const ms = ms: {
88608832 const d = (try timeout.toDurationFromNow(t_io)) orelse
88618833 break :ms std.math.maxInt(windows.DWORD);
......@@ -8867,7 +8839,6 @@ fn sleepWindows(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
88678839
88688840fn sleepWasi(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
88698841 const t: *Threaded = @ptrCast(@alignCast(userdata));
8870 const current_thread = Thread.getCurrent(t);
88718842 const t_io = ioBasic(t);
88728843 const w = std.os.wasi;
88738844
......@@ -8891,14 +8862,13 @@ fn sleepWasi(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
88918862 };
88928863 var event: w.event_t = undefined;
88938864 var nevents: usize = undefined;
8894 try current_thread.beginSyscall();
8865 const syscall: Syscall = try .start();
88958866 _ = w.poll_oneoff(&in, &event, 1, &nevents);
8896 current_thread.endSyscall();
8867 syscall.finish();
88978868}
88988869
88998870fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
89008871 const t: *Threaded = @ptrCast(@alignCast(userdata));
8901 const current_thread = Thread.getCurrent(t);
89028872 const t_io = ioBasic(t);
89038873 const sec_type = @typeInfo(posix.timespec).@"struct".fields[0].type;
89048874 const nsec_type = @typeInfo(posix.timespec).@"struct".fields[1].type;
......@@ -8910,21 +8880,22 @@ fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
89108880 };
89118881 break :t timestampToPosix(d.raw.toNanoseconds());
89128882 };
8913 try current_thread.beginSyscall();
8883 const syscall: Syscall = try .start();
89148884 while (true) {
89158885 switch (posix.errno(posix.system.nanosleep(&timespec, &timespec))) {
89168886 .INTR => {
8917 try current_thread.checkCancel();
8887 try syscall.checkCancel();
89188888 continue;
89198889 },
89208890 // This prong handles success as well as unexpected errors.
8921 else => return current_thread.endSyscall(),
8891 else => return syscall.finish(),
89228892 }
89238893 }
89248894}
89258895
89268896fn select(userdata: ?*anyopaque, futures: []const *Io.AnyFuture) Io.Cancelable!usize {
89278897 const t: *Threaded = @ptrCast(@alignCast(userdata));
8898 _ = t;
89288899
89298900 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
89488919 }
89498920
89508921 errdefer _ = finishSelect(&num_completed, futures);
8951 const thread: *Thread = .getCurrent(t);
89528922
89538923 while (true) {
89548924 const n = num_completed.load(.acquire);
89558925 if (n > 0) break;
89568926 assert(n < futures.len);
8957 try thread.futexWait(&num_completed.raw, n);
8927 try Thread.futexWait(&num_completed.raw, n, null);
89588928 }
89598929 return finishSelect(&num_completed, futures).?;
89608930}
......@@ -8986,7 +8956,7 @@ fn finishSelect(
89868956 const n = num_completed.load(.acquire);
89878957 if (n == expect_completed) break;
89888958 assert(n < expect_completed);
8989 Thread.futexWaitUncancelable(&num_completed.raw, n);
8959 Thread.futexWaitUncancelable(&num_completed.raw, n, null);
89908960 }
89918961 return completed_index;
89928962}
......@@ -8998,37 +8968,37 @@ fn netListenIpPosix(
89988968) IpAddress.ListenError!net.Server {
89998969 if (!have_networking) return error.NetworkDown;
90008970 const t: *Threaded = @ptrCast(@alignCast(userdata));
9001 const current_thread = Thread.getCurrent(t);
8971 _ = t;
90028972 const family = posixAddressFamily(&address);
9003 const socket_fd = try openSocketPosix(current_thread, family, .{
8973 const socket_fd = try openSocketPosix(family, .{
90048974 .mode = options.mode,
90058975 .protocol = options.protocol,
90068976 });
90078977 errdefer posix.close(socket_fd);
90088978
90098979 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);
90118981 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);
90138983 }
90148984
90158985 var storage: PosixAddress = undefined;
90168986 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();
90208990 while (true) {
90218991 switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {
90228992 .SUCCESS => {
9023 current_thread.endSyscall();
8993 syscall.finish();
90248994 break;
90258995 },
90268996 .INTR => {
9027 try current_thread.checkCancel();
8997 try syscall.checkCancel();
90288998 continue;
90298999 },
90309000 else => |e| {
9031 current_thread.endSyscall();
9001 syscall.finish();
90329002 switch (e) {
90339003 .ADDRINUSE => return error.AddressInUse,
90349004 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
......@@ -9038,7 +9008,7 @@ fn netListenIpPosix(
90389008 }
90399009 }
90409010
9041 try posixGetSockName(current_thread, socket_fd, &storage.any, &addr_len);
9011 try posixGetSockName(socket_fd, &storage.any, &addr_len);
90429012 return .{
90439013 .socket = .{
90449014 .handle = socket_fd,
......@@ -9054,9 +9024,8 @@ fn netListenIpWindows(
90549024) IpAddress.ListenError!net.Server {
90559025 if (!have_networking) return error.NetworkDown;
90569026 const t: *Threaded = @ptrCast(@alignCast(userdata));
9057 const current_thread = Thread.getCurrent(t);
90589027 const family = posixAddressFamily(&address);
9059 const socket_handle = try openSocketWsa(t, current_thread, family, .{
9028 const socket_handle = try openSocketWsa(t, family, .{
90609029 .mode = options.mode,
90619030 .protocol = options.protocol,
90629031 });
......@@ -9068,76 +9037,79 @@ fn netListenIpWindows(
90689037 var storage: WsaAddress = undefined;
90699038 var addr_len = addressToWsa(&address, &storage);
90709039
9071 try current_thread.beginSyscall();
9072 while (true) {
9073 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
9074 if (rc != ws2_32.SOCKET_ERROR) {
9075 current_thread.endSyscall();
9076 break;
9077 }
9078 switch (ws2_32.WSAGetLastError()) {
9079 .EINTR => {
9080 try current_thread.checkCancel();
9081 continue;
9082 },
9083 .NOTINITIALISED => {
9084 try initializeWsa(t);
9085 try current_thread.checkCancel();
9086 continue;
9087 },
9088 else => |e| {
9089 current_thread.endSyscall();
9090 switch (e) {
9091 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
9092 .EADDRINUSE => return error.AddressInUse,
9093 .EADDRNOTAVAIL => return error.AddressUnavailable,
9094 .ENOTSOCK => |err| return wsaErrorBug(err),
9095 .EFAULT => |err| return wsaErrorBug(err),
9096 .EINVAL => |err| return wsaErrorBug(err),
9097 .ENOBUFS => return error.SystemResources,
9098 .ENETDOWN => return error.NetworkDown,
9099 else => |err| return windows.unexpectedWSAError(err),
9100 }
9101 },
9040 {
9041 const syscall: Syscall = try .start();
9042 while (true) {
9043 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
9044 if (rc != ws2_32.SOCKET_ERROR) {
9045 syscall.finish();
9046 break;
9047 }
9048 switch (ws2_32.WSAGetLastError()) {
9049 .EINTR => {
9050 try syscall.checkCancel();
9051 continue;
9052 },
9053 .NOTINITIALISED => {
9054 try initializeWsa(t);
9055 try syscall.checkCancel();
9056 continue;
9057 },
9058 else => |e| {
9059 syscall.finish();
9060 switch (e) {
9061 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
9062 .EADDRINUSE => return error.AddressInUse,
9063 .EADDRNOTAVAIL => return error.AddressUnavailable,
9064 .ENOTSOCK => |err| return wsaErrorBug(err),
9065 .EFAULT => |err| return wsaErrorBug(err),
9066 .EINVAL => |err| return wsaErrorBug(err),
9067 .ENOBUFS => return error.SystemResources,
9068 .ENETDOWN => return error.NetworkDown,
9069 else => |err| return windows.unexpectedWSAError(err),
9070 }
9071 },
9072 }
91029073 }
91039074 }
9104
9105 try current_thread.beginSyscall();
9106 while (true) {
9107 const rc = ws2_32.listen(socket_handle, options.kernel_backlog);
9108 if (rc != ws2_32.SOCKET_ERROR) {
9109 current_thread.endSyscall();
9110 break;
9111 }
9112 switch (ws2_32.WSAGetLastError()) {
9113 .EINTR => {
9114 try current_thread.checkCancel();
9115 continue;
9116 },
9117 .NOTINITIALISED => {
9118 try initializeWsa(t);
9119 try current_thread.checkCancel();
9120 continue;
9121 },
9122 else => |e| {
9123 current_thread.endSyscall();
9124 switch (e) {
9125 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
9126 .ENETDOWN => return error.NetworkDown,
9127 .EADDRINUSE => return error.AddressInUse,
9128 .EISCONN => |err| return wsaErrorBug(err),
9129 .EINVAL => |err| return wsaErrorBug(err),
9130 .EMFILE, .ENOBUFS => return error.SystemResources,
9131 .ENOTSOCK => |err| return wsaErrorBug(err),
9132 .EOPNOTSUPP => |err| return wsaErrorBug(err),
9133 .EINPROGRESS => |err| return wsaErrorBug(err),
9134 else => |err| return windows.unexpectedWSAError(err),
9135 }
9136 },
9075 {
9076 const syscall: Syscall = try .start();
9077 while (true) {
9078 const rc = ws2_32.listen(socket_handle, options.kernel_backlog);
9079 if (rc != ws2_32.SOCKET_ERROR) {
9080 syscall.finish();
9081 break;
9082 }
9083 switch (ws2_32.WSAGetLastError()) {
9084 .EINTR => {
9085 try syscall.checkCancel();
9086 continue;
9087 },
9088 .NOTINITIALISED => {
9089 try initializeWsa(t);
9090 try syscall.checkCancel();
9091 continue;
9092 },
9093 else => |e| {
9094 syscall.finish();
9095 switch (e) {
9096 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
9097 .ENETDOWN => return error.NetworkDown,
9098 .EADDRINUSE => return error.AddressInUse,
9099 .EISCONN => |err| return wsaErrorBug(err),
9100 .EINVAL => |err| return wsaErrorBug(err),
9101 .EMFILE, .ENOBUFS => return error.SystemResources,
9102 .ENOTSOCK => |err| return wsaErrorBug(err),
9103 .EOPNOTSUPP => |err| return wsaErrorBug(err),
9104 .EINPROGRESS => |err| return wsaErrorBug(err),
9105 else => |err| return windows.unexpectedWSAError(err),
9106 }
9107 },
9108 }
91379109 }
91389110 }
91399111
9140 try wsaGetSockName(t, current_thread, socket_handle, &storage.any, &addr_len);
9112 try wsaGetSockName(t, socket_handle, &storage.any, &addr_len);
91419113
91429114 return .{
91439115 .socket = .{
......@@ -9165,8 +9137,8 @@ fn netListenUnixPosix(
91659137) net.UnixAddress.ListenError!net.Socket.Handle {
91669138 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
91679139 const t: *Threaded = @ptrCast(@alignCast(userdata));
9168 const current_thread = Thread.getCurrent(t);
9169 const socket_fd = openSocketPosix(current_thread, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
9140 _ = t;
9141 const socket_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
91709142 error.ProtocolUnsupportedBySystem => return error.AddressFamilyUnsupported,
91719143 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
91729144 error.SocketModeUnsupported => return error.AddressFamilyUnsupported,
......@@ -9177,21 +9149,21 @@ fn netListenUnixPosix(
91779149
91789150 var storage: UnixAddress = undefined;
91799151 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();
91839155 while (true) {
91849156 switch (posix.errno(posix.system.listen(socket_fd, options.kernel_backlog))) {
91859157 .SUCCESS => {
9186 current_thread.endSyscall();
9158 syscall.finish();
91879159 break;
91889160 },
91899161 .INTR => {
9190 try current_thread.checkCancel();
9162 try syscall.checkCancel();
91919163 continue;
91929164 },
91939165 else => |e| {
9194 current_thread.endSyscall();
9166 syscall.finish();
91959167 switch (e) {
91969168 .ADDRINUSE => return error.AddressInUse,
91979169 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
......@@ -9211,9 +9183,8 @@ fn netListenUnixWindows(
92119183) net.UnixAddress.ListenError!net.Socket.Handle {
92129184 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
92139185 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) {
92179188 error.ProtocolUnsupportedByAddressFamily => return error.AddressFamilyUnsupported,
92189189 else => |e| return e,
92199190 };
......@@ -9222,22 +9193,22 @@ fn netListenUnixWindows(
92229193 var storage: WsaAddress = undefined;
92239194 const addr_len = addressUnixToWsa(address, &storage);
92249195
9225 try current_thread.beginSyscall();
9196 const syscall: Syscall = try .start();
92269197 while (true) {
92279198 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
92289199 if (rc != ws2_32.SOCKET_ERROR) break;
92299200 switch (ws2_32.WSAGetLastError()) {
92309201 .EINTR => {
9231 try current_thread.checkCancel();
9202 try syscall.checkCancel();
92329203 continue;
92339204 },
92349205 .NOTINITIALISED => {
92359206 try initializeWsa(t);
9236 try current_thread.checkCancel();
9207 try syscall.checkCancel();
92379208 continue;
92389209 },
92399210 else => |e| {
9240 current_thread.endSyscall();
9211 syscall.finish();
92419212 switch (e) {
92429213 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
92439214 .EADDRINUSE => return error.AddressInUse,
......@@ -9254,10 +9225,10 @@ fn netListenUnixWindows(
92549225 }
92559226
92569227 while (true) {
9257 try current_thread.checkCancel();
9228 try syscall.checkCancel();
92589229 const rc = ws2_32.listen(socket_handle, options.kernel_backlog);
92599230 if (rc != ws2_32.SOCKET_ERROR) {
9260 current_thread.endSyscall();
9231 syscall.finish();
92619232 return socket_handle;
92629233 }
92639234 switch (ws2_32.WSAGetLastError()) {
......@@ -9267,7 +9238,7 @@ fn netListenUnixWindows(
92679238 continue;
92689239 },
92699240 else => |e| {
9270 current_thread.endSyscall();
9241 syscall.finish();
92719242 switch (e) {
92729243 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
92739244 .ENETDOWN => return error.NetworkDown,
......@@ -9297,24 +9268,23 @@ fn netListenUnixUnavailable(
92979268}
92989269
92999270fn posixBindUnix(
9300 current_thread: *Thread,
93019271 fd: posix.socket_t,
93029272 addr: *const posix.sockaddr,
93039273 addr_len: posix.socklen_t,
93049274) !void {
9305 try current_thread.beginSyscall();
9275 const syscall: Syscall = try .start();
93069276 while (true) {
93079277 switch (posix.errno(posix.system.bind(fd, addr, addr_len))) {
93089278 .SUCCESS => {
9309 current_thread.endSyscall();
9279 syscall.finish();
93109280 break;
93119281 },
93129282 .INTR => {
9313 try current_thread.checkCancel();
9283 try syscall.checkCancel();
93149284 continue;
93159285 },
93169286 else => |e| {
9317 current_thread.endSyscall();
9287 syscall.finish();
93189288 switch (e) {
93199289 .ACCES => return error.AccessDenied,
93209290 .ADDRINUSE => return error.AddressInUse,
......@@ -9341,24 +9311,23 @@ fn posixBindUnix(
93419311}
93429312
93439313fn posixBind(
9344 current_thread: *Thread,
93459314 socket_fd: posix.socket_t,
93469315 addr: *const posix.sockaddr,
93479316 addr_len: posix.socklen_t,
93489317) !void {
9349 try current_thread.beginSyscall();
9318 const syscall: Syscall = try .start();
93509319 while (true) {
93519320 switch (posix.errno(posix.system.bind(socket_fd, addr, addr_len))) {
93529321 .SUCCESS => {
9353 current_thread.endSyscall();
9322 syscall.finish();
93549323 break;
93559324 },
93569325 .INTR => {
9357 try current_thread.checkCancel();
9326 try syscall.checkCancel();
93589327 continue;
93599328 },
93609329 else => |e| {
9361 current_thread.endSyscall();
9330 syscall.finish();
93629331 switch (e) {
93639332 .ADDRINUSE => return error.AddressInUse,
93649333 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
......@@ -9376,24 +9345,23 @@ fn posixBind(
93769345}
93779346
93789347fn posixConnect(
9379 current_thread: *Thread,
93809348 socket_fd: posix.socket_t,
93819349 addr: *const posix.sockaddr,
93829350 addr_len: posix.socklen_t,
93839351) !void {
9384 try current_thread.beginSyscall();
9352 const syscall: Syscall = try .start();
93859353 while (true) {
93869354 switch (posix.errno(posix.system.connect(socket_fd, addr, addr_len))) {
93879355 .SUCCESS => {
9388 current_thread.endSyscall();
9356 syscall.finish();
93899357 return;
93909358 },
93919359 .INTR => {
9392 try current_thread.checkCancel();
9360 try syscall.checkCancel();
93939361 continue;
93949362 },
93959363 else => |e| {
9396 current_thread.endSyscall();
9364 syscall.finish();
93979365 switch (e) {
93989366 .ADDRNOTAVAIL => return error.AddressUnavailable,
93999367 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
......@@ -9422,24 +9390,23 @@ fn posixConnect(
94229390}
94239391
94249392fn posixConnectUnix(
9425 current_thread: *Thread,
94269393 fd: posix.socket_t,
94279394 addr: *const posix.sockaddr,
94289395 addr_len: posix.socklen_t,
94299396) !void {
9430 try current_thread.beginSyscall();
9397 const syscall: Syscall = try .start();
94319398 while (true) {
94329399 switch (posix.errno(posix.system.connect(fd, addr, addr_len))) {
94339400 .SUCCESS => {
9434 current_thread.endSyscall();
9401 syscall.finish();
94359402 return;
94369403 },
94379404 .INTR => {
9438 try current_thread.checkCancel();
9405 try syscall.checkCancel();
94399406 continue;
94409407 },
94419408 else => |e| {
9442 current_thread.endSyscall();
9409 syscall.finish();
94439410 switch (e) {
94449411 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
94459412 .AGAIN => return error.WouldBlock,
......@@ -9466,24 +9433,23 @@ fn posixConnectUnix(
94669433}
94679434
94689435fn posixGetSockName(
9469 current_thread: *Thread,
94709436 socket_fd: posix.fd_t,
94719437 addr: *posix.sockaddr,
94729438 addr_len: *posix.socklen_t,
94739439) !void {
9474 try current_thread.beginSyscall();
9440 const syscall: Syscall = try .start();
94759441 while (true) {
94769442 switch (posix.errno(posix.system.getsockname(socket_fd, addr, addr_len))) {
94779443 .SUCCESS => {
9478 current_thread.endSyscall();
9444 syscall.finish();
94799445 break;
94809446 },
94819447 .INTR => {
9482 try current_thread.checkCancel();
9448 try syscall.checkCancel();
94839449 continue;
94849450 },
94859451 else => |e| {
9486 current_thread.endSyscall();
9452 syscall.finish();
94879453 switch (e) {
94889454 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
94899455 .FAULT => |err| return errnoBug(err),
......@@ -9499,30 +9465,29 @@ fn posixGetSockName(
94999465
95009466fn wsaGetSockName(
95019467 t: *Threaded,
9502 current_thread: *Thread,
95039468 handle: ws2_32.SOCKET,
95049469 addr: *ws2_32.sockaddr,
95059470 addr_len: *i32,
95069471) !void {
9507 try current_thread.beginSyscall();
9472 const syscall: Syscall = try .start();
95089473 while (true) {
95099474 const rc = ws2_32.getsockname(handle, addr, addr_len);
95109475 if (rc != ws2_32.SOCKET_ERROR) {
9511 current_thread.endSyscall();
9476 syscall.finish();
95129477 return;
95139478 }
95149479 switch (ws2_32.WSAGetLastError()) {
95159480 .EINTR => {
9516 try current_thread.checkCancel();
9481 try syscall.checkCancel();
95179482 continue;
95189483 },
95199484 .NOTINITIALISED => {
95209485 try initializeWsa(t);
9521 try current_thread.checkCancel();
9486 try syscall.checkCancel();
95229487 continue;
95239488 },
95249489 else => |e| {
9525 current_thread.endSyscall();
9490 syscall.finish();
95269491 switch (e) {
95279492 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
95289493 .ENETDOWN => return error.NetworkDown,
......@@ -9536,21 +9501,21 @@ fn wsaGetSockName(
95369501 }
95379502}
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 {
95409505 const o: []const u8 = @ptrCast(&option);
9541 try current_thread.beginSyscall();
9506 const syscall: Syscall = try .start();
95429507 while (true) {
95439508 switch (posix.errno(posix.system.setsockopt(fd, level, opt_name, o.ptr, @intCast(o.len)))) {
95449509 .SUCCESS => {
9545 current_thread.endSyscall();
9510 syscall.finish();
95469511 return;
95479512 },
95489513 .INTR => {
9549 try current_thread.checkCancel();
9514 try syscall.checkCancel();
95509515 continue;
95519516 },
95529517 else => |e| {
9553 current_thread.endSyscall();
9518 syscall.finish();
95549519 switch (e) {
95559520 .BADF => |err| return errnoBug(err), // File descriptor used after closed.
95569521 .NOTSOCK => |err| return errnoBug(err),
......@@ -9592,17 +9557,17 @@ fn netConnectIpPosix(
95929557 if (!have_networking) return error.NetworkDown;
95939558 if (options.timeout != .none) @panic("TODO implement netConnectIpPosix with timeout");
95949559 const t: *Threaded = @ptrCast(@alignCast(userdata));
9595 const current_thread = Thread.getCurrent(t);
9560 _ = t;
95969561 const family = posixAddressFamily(address);
9597 const socket_fd = try openSocketPosix(current_thread, family, .{
9562 const socket_fd = try openSocketPosix(family, .{
95989563 .mode = options.mode,
95999564 .protocol = options.protocol,
96009565 });
96019566 errdefer posix.close(socket_fd);
96029567 var storage: PosixAddress = undefined;
96039568 var addr_len = addressToPosix(address, &storage);
9604 try posixConnect(current_thread, socket_fd, &storage.any, addr_len);
9605 try posixGetSockName(current_thread, socket_fd, &storage.any, &addr_len);
9569 try posixConnect(socket_fd, &storage.any, addr_len);
9570 try posixGetSockName(socket_fd, &storage.any, &addr_len);
96069571 return .{ .socket = .{
96079572 .handle = socket_fd,
96089573 .address = addressFromPosix(&storage),
......@@ -9617,9 +9582,8 @@ fn netConnectIpWindows(
96179582 if (!have_networking) return error.NetworkDown;
96189583 if (options.timeout != .none) @panic("TODO implement netConnectIpWindows with timeout");
96199584 const t: *Threaded = @ptrCast(@alignCast(userdata));
9620 const current_thread = Thread.getCurrent(t);
96219585 const family = posixAddressFamily(address);
9622 const socket_handle = try openSocketWsa(t, current_thread, family, .{
9586 const socket_handle = try openSocketWsa(t, family, .{
96239587 .mode = options.mode,
96249588 .protocol = options.protocol,
96259589 });
......@@ -9628,25 +9592,25 @@ fn netConnectIpWindows(
96289592 var storage: WsaAddress = undefined;
96299593 var addr_len = addressToWsa(address, &storage);
96309594
9631 try current_thread.beginSyscall();
9595 const syscall: Syscall = try .start();
96329596 while (true) {
96339597 const rc = ws2_32.connect(socket_handle, &storage.any, addr_len);
96349598 if (rc != ws2_32.SOCKET_ERROR) {
9635 current_thread.endSyscall();
9599 syscall.finish();
96369600 break;
96379601 }
96389602 switch (ws2_32.WSAGetLastError()) {
96399603 .EINTR => {
9640 try current_thread.checkCancel();
9604 try syscall.checkCancel();
96419605 continue;
96429606 },
96439607 .NOTINITIALISED => {
96449608 try initializeWsa(t);
9645 try current_thread.checkCancel();
9609 try syscall.checkCancel();
96469610 continue;
96479611 },
96489612 else => |e| {
9649 current_thread.endSyscall();
9613 syscall.finish();
96509614 switch (e) {
96519615 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
96529616 .EADDRNOTAVAIL => return error.AddressUnavailable,
......@@ -9669,7 +9633,7 @@ fn netConnectIpWindows(
96699633 }
96709634 }
96719635
9672 try wsaGetSockName(t, current_thread, socket_handle, &storage.any, &addr_len);
9636 try wsaGetSockName(t, socket_handle, &storage.any, &addr_len);
96739637
96749638 return .{ .socket = .{
96759639 .handle = socket_handle,
......@@ -9694,15 +9658,15 @@ fn netConnectUnixPosix(
96949658) net.UnixAddress.ConnectError!net.Socket.Handle {
96959659 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
96969660 const t: *Threaded = @ptrCast(@alignCast(userdata));
9697 const current_thread = Thread.getCurrent(t);
9698 const socket_fd = openSocketPosix(current_thread, posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
9661 _ = t;
9662 const socket_fd = openSocketPosix(posix.AF.UNIX, .{ .mode = .stream }) catch |err| switch (err) {
96999663 error.OptionUnsupported => return error.Unexpected,
97009664 else => |e| return e,
97019665 };
97029666 errdefer posix.close(socket_fd);
97039667 var storage: UnixAddress = undefined;
97049668 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);
97069670 return socket_fd;
97079671}
97089672
......@@ -9712,9 +9676,8 @@ fn netConnectUnixWindows(
97129676) net.UnixAddress.ConnectError!net.Socket.Handle {
97139677 if (!net.has_unix_sockets) return error.AddressFamilyUnsupported;
97149678 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 });
97189681 errdefer closeSocketWindows(socket_handle);
97199682 var storage: WsaAddress = undefined;
97209683 const addr_len = addressUnixToWsa(address, &storage);
......@@ -9762,14 +9725,14 @@ fn netBindIpPosix(
97629725) IpAddress.BindError!net.Socket {
97639726 if (!have_networking) return error.NetworkDown;
97649727 const t: *Threaded = @ptrCast(@alignCast(userdata));
9765 const current_thread = Thread.getCurrent(t);
9728 _ = t;
97669729 const family = posixAddressFamily(address);
9767 const socket_fd = try openSocketPosix(current_thread, family, options);
9730 const socket_fd = try openSocketPosix(family, options);
97689731 errdefer posix.close(socket_fd);
97699732 var storage: PosixAddress = undefined;
97709733 var addr_len = addressToPosix(address, &storage);
9771 try posixBind(current_thread, socket_fd, &storage.any, addr_len);
9772 try posixGetSockName(current_thread, socket_fd, &storage.any, &addr_len);
9734 try posixBind(socket_fd, &storage.any, addr_len);
9735 try posixGetSockName(socket_fd, &storage.any, &addr_len);
97739736 return .{
97749737 .handle = socket_fd,
97759738 .address = addressFromPosix(&storage),
......@@ -9783,9 +9746,8 @@ fn netBindIpWindows(
97839746) IpAddress.BindError!net.Socket {
97849747 if (!have_networking) return error.NetworkDown;
97859748 const t: *Threaded = @ptrCast(@alignCast(userdata));
9786 const current_thread = Thread.getCurrent(t);
97879749 const family = posixAddressFamily(address);
9788 const socket_handle = try openSocketWsa(t, current_thread, family, .{
9750 const socket_handle = try openSocketWsa(t, family, .{
97899751 .mode = options.mode,
97909752 .protocol = options.protocol,
97919753 });
......@@ -9794,25 +9756,25 @@ fn netBindIpWindows(
97949756 var storage: WsaAddress = undefined;
97959757 var addr_len = addressToWsa(address, &storage);
97969758
9797 try current_thread.beginSyscall();
9759 const syscall: Syscall = try .start();
97989760 while (true) {
97999761 const rc = ws2_32.bind(socket_handle, &storage.any, addr_len);
98009762 if (rc != ws2_32.SOCKET_ERROR) {
9801 current_thread.endSyscall();
9763 syscall.finish();
98029764 break;
98039765 }
98049766 switch (ws2_32.WSAGetLastError()) {
98059767 .EINTR => {
9806 try current_thread.checkCancel();
9768 try syscall.checkCancel();
98079769 continue;
98089770 },
98099771 .NOTINITIALISED => {
98109772 try initializeWsa(t);
9811 try current_thread.checkCancel();
9773 try syscall.checkCancel();
98129774 continue;
98139775 },
98149776 else => |e| {
9815 current_thread.endSyscall();
9777 syscall.finish();
98169778 switch (e) {
98179779 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
98189780 .EADDRINUSE => return error.AddressInUse,
......@@ -9828,7 +9790,7 @@ fn netBindIpWindows(
98289790 }
98299791 }
98309792
9831 try wsaGetSockName(t, current_thread, socket_handle, &storage.any, &addr_len);
9793 try wsaGetSockName(t, socket_handle, &storage.any, &addr_len);
98329794
98339795 return .{
98349796 .handle = socket_handle,
......@@ -9848,7 +9810,6 @@ fn netBindIpUnavailable(
98489810}
98499811
98509812fn openSocketPosix(
9851 current_thread: *Thread,
98529813 family: posix.sa_family_t,
98539814 options: IpAddress.BindOptions,
98549815) error{
......@@ -9865,7 +9826,7 @@ fn openSocketPosix(
98659826}!posix.socket_t {
98669827 const mode = posixSocketMode(options.mode);
98679828 const protocol = posixProtocol(options.protocol);
9868 try current_thread.beginSyscall();
9829 const syscall: Syscall = try .start();
98699830 const socket_fd = while (true) {
98709831 const flags: u32 = mode | if (socket_flags_unsupported) 0 else posix.SOCK.CLOEXEC;
98719832 const socket_rc = posix.system.socket(family, flags, protocol);
......@@ -9874,25 +9835,25 @@ fn openSocketPosix(
98749835 const fd: posix.fd_t = @intCast(socket_rc);
98759836 errdefer posix.close(fd);
98769837 if (socket_flags_unsupported) while (true) {
9877 try current_thread.checkCancel();
9838 try syscall.checkCancel();
98789839 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
98799840 .SUCCESS => break,
98809841 .INTR => continue,
98819842 else => |err| {
9882 current_thread.endSyscall();
9843 syscall.finish();
98839844 return posix.unexpectedErrno(err);
98849845 },
98859846 }
98869847 };
9887 current_thread.endSyscall();
9848 syscall.finish();
98889849 break fd;
98899850 },
98909851 .INTR => {
9891 try current_thread.checkCancel();
9852 try syscall.checkCancel();
98929853 continue;
98939854 },
98949855 else => |e| {
9895 current_thread.endSyscall();
9856 syscall.finish();
98969857 switch (e) {
98979858 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
98989859 .INVAL => return error.ProtocolUnsupportedBySystem,
......@@ -9911,7 +9872,7 @@ fn openSocketPosix(
99119872
99129873 if (options.ip6_only) {
99139874 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);
99159876 }
99169877
99179878 return socket_fd;
......@@ -9919,32 +9880,31 @@ fn openSocketPosix(
99199880
99209881fn openSocketWsa(
99219882 t: *Threaded,
9922 current_thread: *Thread,
99239883 family: posix.sa_family_t,
99249884 options: IpAddress.BindOptions,
99259885) !ws2_32.SOCKET {
99269886 const mode = posixSocketMode(options.mode);
99279887 const protocol = posixProtocol(options.protocol);
99289888 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();
99309890 while (true) {
99319891 const rc = ws2_32.WSASocketW(family, @bitCast(mode), @bitCast(protocol), null, 0, flags);
99329892 if (rc != ws2_32.INVALID_SOCKET) {
9933 current_thread.endSyscall();
9893 syscall.finish();
99349894 return rc;
99359895 }
99369896 switch (ws2_32.WSAGetLastError()) {
99379897 .EINTR => {
9938 try current_thread.checkCancel();
9898 try syscall.checkCancel();
99399899 continue;
99409900 },
99419901 .NOTINITIALISED => {
99429902 try initializeWsa(t);
9943 try current_thread.checkCancel();
9903 try syscall.checkCancel();
99449904 continue;
99459905 },
99469906 else => |e| {
9947 current_thread.endSyscall();
9907 syscall.finish();
99489908 switch (e) {
99499909 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
99509910 .EAFNOSUPPORT => return error.AddressFamilyUnsupported,
......@@ -9961,10 +9921,10 @@ fn openSocketWsa(
99619921fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Server.AcceptError!net.Stream {
99629922 if (!have_networking) return error.NetworkDown;
99639923 const t: *Threaded = @ptrCast(@alignCast(userdata));
9964 const current_thread = Thread.getCurrent(t);
9924 _ = t;
99659925 var storage: PosixAddress = undefined;
99669926 var addr_len: posix.socklen_t = @sizeOf(PosixAddress);
9967 try current_thread.beginSyscall();
9927 const syscall: Syscall = try .start();
99689928 const fd = while (true) {
99699929 const rc = if (have_accept4)
99709930 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
99759935 const fd: posix.fd_t = @intCast(rc);
99769936 errdefer posix.close(fd);
99779937 if (!have_accept4) while (true) {
9978 try current_thread.checkCancel();
9938 try syscall.checkCancel();
99799939 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
99809940 .SUCCESS => break,
99819941 .INTR => continue,
99829942 else => |err| {
9983 current_thread.endSyscall();
9943 syscall.finish();
99849944 return posix.unexpectedErrno(err);
99859945 },
99869946 }
99879947 };
9988 current_thread.endSyscall();
9948 syscall.finish();
99899949 break fd;
99909950 },
99919951 .INTR => {
9992 try current_thread.checkCancel();
9952 try syscall.checkCancel();
99939953 continue;
99949954 },
99959955 else => |e| {
9996 current_thread.endSyscall();
9956 syscall.finish();
99979957 switch (e) {
99989958 .AGAIN => |err| return errnoBug(err),
99999959 .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
100229982fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net.Server.AcceptError!net.Stream {
100239983 if (!have_networking) return error.NetworkDown;
100249984 const t: *Threaded = @ptrCast(@alignCast(userdata));
10025 const current_thread = Thread.getCurrent(t);
100269985 var storage: WsaAddress = undefined;
100279986 var addr_len: i32 = @sizeOf(WsaAddress);
10028 try current_thread.beginSyscall();
9987 const syscall: Syscall = try .start();
100299988 while (true) {
100309989 const rc = ws2_32.accept(listen_handle, &storage.any, &addr_len);
100319990 if (rc != ws2_32.INVALID_SOCKET) {
10032 current_thread.endSyscall();
9991 syscall.finish();
100339992 return .{ .socket = .{
100349993 .handle = rc,
100359994 .address = addressFromWsa(&storage),
......@@ -10037,16 +9996,16 @@ fn netAcceptWindows(userdata: ?*anyopaque, listen_handle: net.Socket.Handle) net
100379996 }
100389997 switch (ws2_32.WSAGetLastError()) {
100399998 .EINTR => {
10040 try current_thread.checkCancel();
9999 try syscall.checkCancel();
1004110000 continue;
1004210001 },
1004310002 .NOTINITIALISED => {
1004410003 try initializeWsa(t);
10045 try current_thread.checkCancel();
10004 try syscall.checkCancel();
1004610005 continue;
1004710006 },
1004810007 else => |e| {
10049 current_thread.endSyscall();
10008 syscall.finish();
1005010009 switch (e) {
1005110010 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
1005210011 .ECONNRESET => return error.ConnectionAborted,
......@@ -10073,7 +10032,7 @@ fn netAcceptUnavailable(userdata: ?*anyopaque, listen_handle: net.Socket.Handle)
1007310032fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
1007410033 if (!have_networking) return error.NetworkDown;
1007510034 const t: *Threaded = @ptrCast(@alignCast(userdata));
10076 const current_thread = Thread.getCurrent(t);
10035 _ = t;
1007710036
1007810037 var iovecs_buffer: [max_iovecs_len]posix.iovec = undefined;
1007910038 var i: usize = 0;
......@@ -10088,20 +10047,20 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
1008810047 assert(dest[0].len > 0);
1008910048
1009010049 if (native_os == .wasi and !builtin.link_libc) {
10091 try current_thread.beginSyscall();
10050 const syscall: Syscall = try .start();
1009210051 while (true) {
1009310052 var n: usize = undefined;
1009410053 switch (std.os.wasi.fd_read(fd, dest.ptr, dest.len, &n)) {
1009510054 .SUCCESS => {
10096 current_thread.endSyscall();
10055 syscall.finish();
1009710056 return n;
1009810057 },
1009910058 .INTR => {
10100 try current_thread.checkCancel();
10059 try syscall.checkCancel();
1010110060 continue;
1010210061 },
1010310062 else => |e| {
10104 current_thread.endSyscall();
10063 syscall.finish();
1010510064 switch (e) {
1010610065 .INVAL => |err| return errnoBug(err),
1010710066 .FAULT => |err| return errnoBug(err),
......@@ -10120,20 +10079,20 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
1012010079 }
1012110080 }
1012210081
10123 try current_thread.beginSyscall();
10082 const syscall: Syscall = try .start();
1012410083 while (true) {
1012510084 const rc = posix.system.readv(fd, dest.ptr, @intCast(dest.len));
1012610085 switch (posix.errno(rc)) {
1012710086 .SUCCESS => {
10128 current_thread.endSyscall();
10087 syscall.finish();
1012910088 return @intCast(rc);
1013010089 },
1013110090 .INTR => {
10132 try current_thread.checkCancel();
10091 try syscall.checkCancel();
1013310092 continue;
1013410093 },
1013510094 else => |e| {
10136 current_thread.endSyscall();
10095 syscall.finish();
1013710096 switch (e) {
1013810097 .INVAL => |err| return errnoBug(err),
1013910098 .FAULT => |err| return errnoBug(err),
......@@ -10156,7 +10115,6 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
1015610115fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8) net.Stream.Reader.Error!usize {
1015710116 if (!have_networking) return error.NetworkDown;
1015810117 const t: *Threaded = @ptrCast(@alignCast(userdata));
10159 const current_thread = Thread.getCurrent(t);
1016010118
1016110119 const bufs = b: {
1016210120 var iovec_buffer: [max_iovecs_len]ws2_32.WSABUF = undefined;
......@@ -10184,7 +10142,7 @@ fn netReadWindows(userdata: ?*anyopaque, handle: net.Socket.Handle, data: [][]u8
1018410142 };
1018510143
1018610144 while (true) {
10187 try current_thread.checkCancel();
10145 try Thread.checkCancel();
1018810146
1018910147 var flags: u32 = 0;
1019010148 var overlapped: windows.OVERLAPPED = std.mem.zeroes(windows.OVERLAPPED);
......@@ -10244,7 +10202,6 @@ fn netSendPosix(
1024410202) struct { ?net.Socket.SendError, usize } {
1024510203 if (!have_networking) return .{ error.NetworkDown, 0 };
1024610204 const t: *Threaded = @ptrCast(@alignCast(userdata));
10247 const current_thread = Thread.getCurrent(t);
1024810205
1024910206 const posix_flags: u32 =
1025010207 @as(u32, if (@hasDecl(posix.MSG, "CONFIRM") and flags.confirm) posix.MSG.CONFIRM else 0) |
......@@ -10257,10 +10214,10 @@ fn netSendPosix(
1025710214 var i: usize = 0;
1025810215 while (messages.len - i != 0) {
1025910216 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 };
1026110218 continue;
1026210219 }
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 };
1026410221 i += 1;
1026510222 }
1026610223 return .{ null, i };
......@@ -10296,7 +10253,6 @@ fn netSendUnavailable(
1029610253
1029710254fn netSendOne(
1029810255 t: *Threaded,
10299 current_thread: *Thread,
1030010256 handle: net.Socket.Handle,
1030110257 message: *net.OutgoingMessage,
1030210258 flags: u32,
......@@ -10313,27 +10269,27 @@ fn netSendOne(
1031310269 .controllen = @intCast(message.control.len),
1031410270 .flags = 0,
1031510271 };
10316 try current_thread.beginSyscall();
10272 const syscall: Syscall = try .start();
1031710273 while (true) {
1031810274 const rc = posix.system.sendmsg(handle, &msg, flags);
1031910275 if (is_windows) {
1032010276 if (rc != ws2_32.SOCKET_ERROR) {
10321 current_thread.endSyscall();
10277 syscall.finish();
1032210278 message.data_len = @intCast(rc);
1032310279 return;
1032410280 }
1032510281 switch (ws2_32.WSAGetLastError()) {
1032610282 .EINTR => {
10327 try current_thread.checkCancel();
10283 try syscall.checkCancel();
1032810284 continue;
1032910285 },
1033010286 .NOTINITIALISED => {
1033110287 try initializeWsa(t);
10332 try current_thread.checkCancel();
10288 try syscall.checkCancel();
1033310289 continue;
1033410290 },
1033510291 else => |e| {
10336 current_thread.endSyscall();
10292 syscall.finish();
1033710293 switch (e) {
1033810294 .ECANCELLED, .E_CANCELLED, .OPERATION_ABORTED => return error.Canceled,
1033910295 .EACCES => return error.AccessDenied,
......@@ -10359,16 +10315,16 @@ fn netSendOne(
1035910315 }
1036010316 switch (posix.errno(rc)) {
1036110317 .SUCCESS => {
10362 current_thread.endSyscall();
10318 syscall.finish();
1036310319 message.data_len = @intCast(rc);
1036410320 return;
1036510321 },
1036610322 .INTR => {
10367 try current_thread.checkCancel();
10323 try syscall.checkCancel();
1036810324 continue;
1036910325 },
1037010326 else => |e| {
10371 current_thread.endSyscall();
10327 syscall.finish();
1037210328 switch (e) {
1037310329 .ACCES => return error.AccessDenied,
1037410330 .ALREADY => return error.FastOpenAlreadyInProgress,
......@@ -10397,7 +10353,6 @@ fn netSendOne(
1039710353}
1039810354
1039910355fn netSendMany(
10400 current_thread: *Thread,
1040110356 handle: net.Socket.Handle,
1040210357 messages: []net.OutgoingMessage,
1040310358 flags: u32,
......@@ -10427,12 +10382,12 @@ fn netSendMany(
1042710382 };
1042810383 }
1042910384
10430 try current_thread.beginSyscall();
10385 const syscall: Syscall = try .start();
1043110386 while (true) {
1043210387 const rc = posix.system.sendmmsg(handle, clamped_msgs.ptr, @intCast(clamped_msgs.len), flags);
1043310388 switch (posix.errno(rc)) {
1043410389 .SUCCESS => {
10435 current_thread.endSyscall();
10390 syscall.finish();
1043610391 const n: usize = @intCast(rc);
1043710392 for (clamped_messages[0..n], clamped_msgs[0..n]) |*message, *msg| {
1043810393 message.data_len = msg.len;
......@@ -10440,11 +10395,11 @@ fn netSendMany(
1044010395 return n;
1044110396 },
1044210397 .INTR => {
10443 try current_thread.checkCancel();
10398 try syscall.checkCancel();
1044410399 continue;
1044510400 },
1044610401 else => |e| {
10447 current_thread.endSyscall();
10402 syscall.finish();
1044810403 switch (e) {
1044910404 .AGAIN => |err| return errnoBug(err),
1045010405 .ALREADY => return error.FastOpenAlreadyInProgress,
......@@ -10482,7 +10437,6 @@ fn netReceivePosix(
1048210437) struct { ?net.Socket.ReceiveTimeoutError, usize } {
1048310438 if (!have_networking) return .{ error.NetworkDown, 0 };
1048410439 const t: *Threaded = @ptrCast(@alignCast(userdata));
10485 const current_thread = Thread.getCurrent(t);
1048610440 const t_io = io(t);
1048710441
1048810442 // recvmmsg is useless, here's why:
......@@ -10528,9 +10482,12 @@ fn netReceivePosix(
1052810482 .flags = undefined,
1052910483 };
1053010484
10531 current_thread.beginSyscall() catch |err| return .{ err, message_i };
10532 const recv_rc = posix.system.recvmsg(handle, &msg, posix_flags);
10533 current_thread.endSyscall();
10485 const recv_rc = rc: {
10486 const syscall = Syscall.start() catch |err| return .{ err, message_i };
10487 const rc = posix.system.recvmsg(handle, &msg, posix_flags);
10488 syscall.finish();
10489 break :rc rc;
10490 };
1053410491 switch (posix.errno(recv_rc)) {
1053510492 .SUCCESS => {
1053610493 const data = remaining_data_buffer[0..@intCast(recv_rc)];
......@@ -10560,9 +10517,9 @@ fn netReceivePosix(
1056010517 break :t @intCast(@min(max_poll_ms, duration.raw.toMilliseconds()));
1056110518 } 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 };
1056410521 const poll_rc = posix.system.poll(&poll_fds, poll_fds.len, timeout_ms);
10565 current_thread.endSyscall();
10522 syscall.finish();
1056610523
1056710524 switch (posix.errno(poll_rc)) {
1056810525 .SUCCESS => {
......@@ -10648,7 +10605,7 @@ fn netWritePosix(
1064810605) net.Stream.Writer.Error!usize {
1064910606 if (!have_networking) return error.NetworkDown;
1065010607 const t: *Threaded = @ptrCast(@alignCast(userdata));
10651 const current_thread = Thread.getCurrent(t);
10608 _ = t;
1065210609
1065310610 var iovecs: [max_iovecs_len]posix.iovec_const = undefined;
1065410611 var msg: posix.msghdr_const = .{
......@@ -10690,20 +10647,20 @@ fn netWritePosix(
1069010647 };
1069110648 const flags = posix.MSG.NOSIGNAL;
1069210649
10693 try current_thread.beginSyscall();
10650 const syscall: Syscall = try .start();
1069410651 while (true) {
1069510652 const rc = posix.system.sendmsg(fd, &msg, flags);
1069610653 switch (posix.errno(rc)) {
1069710654 .SUCCESS => {
10698 current_thread.endSyscall();
10655 syscall.finish();
1069910656 return @intCast(rc);
1070010657 },
1070110658 .INTR => {
10702 try current_thread.checkCancel();
10659 try syscall.checkCancel();
1070310660 continue;
1070410661 },
1070510662 else => |e| {
10706 current_thread.endSyscall();
10663 syscall.finish();
1070710664 switch (e) {
1070810665 .ACCES => |err| return errnoBug(err),
1070910666 .AGAIN => |err| return errnoBug(err),
......@@ -10740,7 +10697,6 @@ fn netWriteWindows(
1074010697 splat: usize,
1074110698) net.Stream.Writer.Error!usize {
1074210699 const t: *Threaded = @ptrCast(@alignCast(userdata));
10743 const current_thread = Thread.getCurrent(t);
1074410700 comptime assert(native_os == .windows);
1074510701
1074610702 var iovecs: [max_iovecs_len]ws2_32.WSABUF = undefined;
......@@ -10774,7 +10730,7 @@ fn netWriteWindows(
1077410730 };
1077510731
1077610732 while (true) {
10777 try current_thread.checkCancel();
10733 try Thread.checkCancel();
1077810734
1077910735 var n: u32 = undefined;
1078010736 var overlapped: windows.OVERLAPPED = std.mem.zeroes(windows.OVERLAPPED);
......@@ -10884,7 +10840,7 @@ fn netCloseUnavailable(userdata: ?*anyopaque, handles: []const net.Socket.Handle
1088410840fn netShutdownPosix(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void {
1088510841 if (!have_networking) return error.NetworkDown;
1088610842 const t: *Threaded = @ptrCast(@alignCast(userdata));
10887 const current_thread = Thread.getCurrent(t);
10843 _ = t;
1088810844
1088910845 const posix_how: i32 = switch (how) {
1089010846 .recv => posix.SHUT.RD,
......@@ -10892,19 +10848,16 @@ fn netShutdownPosix(userdata: ?*anyopaque, handle: net.Socket.Handle, how: net.S
1089210848 .both => posix.SHUT.RDWR,
1089310849 };
1089410850
10895 try current_thread.beginSyscall();
10851 const syscall: Syscall = try .start();
1089610852 while (true) {
1089710853 switch (posix.errno(posix.system.shutdown(handle, posix_how))) {
10898 .SUCCESS => {
10899 current_thread.endSyscall();
10900 return;
10901 },
10854 .SUCCESS => return syscall.finish(),
1090210855 .INTR => {
10903 try current_thread.checkCancel();
10856 try syscall.checkCancel();
1090410857 continue;
1090510858 },
1090610859 else => |e| {
10907 current_thread.endSyscall();
10860 syscall.finish();
1090810861 switch (e) {
1090910862 .BADF, .NOTSOCK, .INVAL => |err| return errnoBug(err),
1091010863 .NOTCONN => return error.SocketUnconnected,
......@@ -10970,10 +10923,10 @@ fn netInterfaceNameResolve(
1097010923) net.Interface.Name.ResolveError!net.Interface {
1097110924 if (!have_networking) return error.InterfaceNotFound;
1097210925 const t: *Threaded = @ptrCast(@alignCast(userdata));
10973 const current_thread = Thread.getCurrent(t);
10926 _ = t;
1097410927
1097510928 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) {
1097710930 error.ProcessFdQuotaExceeded => return error.SystemResources,
1097810931 error.SystemFdQuotaExceeded => return error.SystemResources,
1097910932 error.AddressFamilyUnsupported => return error.Unexpected,
......@@ -10990,19 +10943,19 @@ fn netInterfaceNameResolve(
1099010943 .ifru = undefined,
1099110944 };
1099210945
10993 try current_thread.beginSyscall();
10946 const syscall: Syscall = try .start();
1099410947 while (true) {
1099510948 switch (posix.errno(posix.system.ioctl(sock_fd, posix.SIOCGIFINDEX, @intFromPtr(&ifr)))) {
1099610949 .SUCCESS => {
10997 current_thread.endSyscall();
10950 syscall.finish();
1099810951 return .{ .index = @bitCast(ifr.ifru.ivalue) };
1099910952 },
1100010953 .INTR => {
11001 try current_thread.checkCancel();
10954 try syscall.checkCancel();
1100210955 continue;
1100310956 },
1100410957 else => |e| {
11005 current_thread.endSyscall();
10958 syscall.finish();
1100610959 switch (e) {
1100710960 .INVAL => |err| return errnoBug(err), // Bad parameters.
1100810961 .NOTTY => |err| return errnoBug(err),
......@@ -11019,12 +10972,12 @@ fn netInterfaceNameResolve(
1101910972 }
1102010973
1102110974 if (native_os == .windows) {
11022 try current_thread.checkCancel();
10975 try Thread.checkCancel();
1102310976 @panic("TODO implement netInterfaceNameResolve for Windows");
1102410977 }
1102510978
1102610979 if (builtin.link_libc) {
11027 try current_thread.checkCancel();
10980 try Thread.checkCancel();
1102810981 const index = std.c.if_nametoindex(&name.bytes);
1102910982 if (index == 0) return error.InterfaceNotFound;
1103010983 return .{ .index = @bitCast(index) };
......@@ -11044,8 +10997,8 @@ fn netInterfaceNameResolveUnavailable(
1104410997
1104510998fn netInterfaceName(userdata: ?*anyopaque, interface: net.Interface) net.Interface.NameError!net.Interface.Name {
1104610999 const t: *Threaded = @ptrCast(@alignCast(userdata));
11047 const current_thread = Thread.getCurrent(t);
11048 try current_thread.checkCancel();
11000 _ = t;
11001 try Thread.checkCancel();
1104911002
1105011003 if (native_os == .linux) {
1105111004 _ = interface;
......@@ -11104,7 +11057,6 @@ fn netLookupFallible(
1110411057) (net.HostName.LookupError || Io.QueueClosedError)!void {
1110511058 if (!have_networking) return error.NetworkDown;
1110611059
11107 const current_thread: *Thread = .getCurrent(t);
1110811060 const t_io = io(t);
1110911061 const name = host_name.bytes;
1111011062 assert(name.len <= HostName.max_len);
......@@ -11145,7 +11097,7 @@ fn netLookupFallible(
1114511097 var res: *ws2_32.ADDRINFOEXW = undefined;
1114611098 const timeout: ?*ws2_32.timeval = null;
1114711099 while (true) {
11148 try current_thread.checkCancel(); // TODO make requestCancel call GetAddrInfoExCancel
11100 try Thread.checkCancel();
1114911101 // TODO make this append to the queue eagerly rather than blocking until
1115011102 // the whole thing finishes
1115111103 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(
1129211244 .next = null,
1129311245 };
1129411246 var res: ?*posix.addrinfo = null;
11295 try current_thread.beginSyscall();
11247 const syscall: Syscall = try .start();
1129611248 while (true) {
1129711249 switch (posix.system.getaddrinfo(name_c.ptr, port_c.ptr, &hints, &res)) {
1129811250 @as(posix.system.EAI, @enumFromInt(0)) => {
11299 current_thread.endSyscall();
11251 syscall.finish();
1130011252 break;
1130111253 },
1130211254 .SYSTEM => switch (posix.errno(-1)) {
1130311255 .INTR => {
11304 try current_thread.checkCancel();
11256 try syscall.checkCancel();
1130511257 continue;
1130611258 },
1130711259 else => |e| {
11308 current_thread.endSyscall();
11260 syscall.finish();
1130911261 return posix.unexpectedErrno(e);
1131011262 },
1131111263 },
1131211264 else => |e| {
11313 current_thread.endSyscall();
11265 syscall.finish();
1131411266 switch (e) {
1131511267 .ADDRFAMILY => return error.AddressFamilyUnsupported,
1131611268 .AGAIN => return error.NameServerFailure,
......@@ -11397,15 +11349,15 @@ fn unlockStderr(userdata: ?*anyopaque) void {
1139711349fn processSetCurrentDir(userdata: ?*anyopaque, dir: Dir) std.process.SetCurrentDirError!void {
1139811350 if (native_os == .wasi) return error.OperationUnsupported;
1139911351 const t: *Threaded = @ptrCast(@alignCast(userdata));
11400 const current_thread = Thread.getCurrent(t);
11352 _ = t;
1140111353
1140211354 if (is_windows) {
11403 try current_thread.checkCancel();
11355 try Thread.checkCancel();
1140411356 var dir_path_buffer: [windows.PATH_MAX_WIDE]u16 = undefined;
1140511357 // TODO move GetFinalPathNameByHandle logic into std.Io.Threaded and add cancel checks
1140611358 const dir_path = try windows.GetFinalPathNameByHandle(dir.handle, .{}, &dir_path_buffer);
1140711359 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();
1140911361 var nt_name: windows.UNICODE_STRING = .{
1141011362 .Length = path_len_bytes,
1141111363 .MaximumLength = path_len_bytes,
......@@ -11427,32 +11379,32 @@ fn processSetCurrentDir(userdata: ?*anyopaque, dir: Dir) std.process.SetCurrentD
1142711379
1142811380 if (dir.handle == posix.AT.FDCWD) return;
1142911381
11430 try current_thread.beginSyscall();
11382 const syscall: Syscall = try .start();
1143111383 while (true) {
1143211384 switch (posix.errno(posix.system.fchdir(dir.handle))) {
11433 .SUCCESS => return current_thread.endSyscall(),
11385 .SUCCESS => return syscall.finish(),
1143411386 .INTR => {
11435 try current_thread.checkCancel();
11387 try syscall.checkCancel();
1143611388 continue;
1143711389 },
1143811390 .ACCES => {
11439 current_thread.endSyscall();
11391 syscall.finish();
1144011392 return error.AccessDenied;
1144111393 },
1144211394 .BADF => |err| {
11443 current_thread.endSyscall();
11395 syscall.finish();
1144411396 return errnoBug(err);
1144511397 },
1144611398 .NOTDIR => {
11447 current_thread.endSyscall();
11399 syscall.finish();
1144811400 return error.NotDir;
1144911401 },
1145011402 .IO => {
11451 current_thread.endSyscall();
11403 syscall.finish();
1145211404 return error.FileSystem;
1145311405 },
1145411406 else => |err| {
11455 current_thread.endSyscall();
11407 syscall.finish();
1145611408 return posix.unexpectedErrno(err);
1145711409 },
1145811410 }