authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-16 22:04:44-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:50-07:00
logec9dfc540b95a5577074e8915670ac2920b32f64
tree634972cab1012f75f81801fd5403af9f6f1e7132
parentf8ea00bd6dccba678901b50904972c017c9e66a1

std.Io.Threaded: handle ECANCELED

none of these APIs are documented to return this error code, but it would be cool if they did.

1 files changed, 64 insertions(+), 2 deletions(-)

lib/std/Io/Threaded.zig+64-2
......@@ -882,6 +882,8 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Io.Dir, sub_path: []const u8, mode:
882882 switch (posix.errno(posix.system.mkdirat(dir.handle, sub_path_posix, mode))) {
883883 .SUCCESS => return,
884884 .INTR => continue,
885 .CANCELED => return error.Canceled,
886
885887 .ACCES => return error.AccessDenied,
886888 .BADF => |err| return errnoBug(err),
887889 .PERM => return error.PermissionDenied,
......@@ -940,6 +942,8 @@ fn dirStatPathLinux(
940942 switch (linux.E.init(rc)) {
941943 .SUCCESS => return statFromLinux(&statx),
942944 .INTR => continue,
945 .CANCELED => return error.Canceled,
946
943947 .ACCES => return error.AccessDenied,
944948 .BADF => |err| return errnoBug(err),
945949 .FAULT => |err| return errnoBug(err),
......@@ -973,6 +977,8 @@ fn dirStatPathPosix(
973977 switch (posix.errno(fstatat_sym(dir.handle, sub_path_posix, &stat, flags))) {
974978 .SUCCESS => return statFromPosix(&stat),
975979 .INTR => continue,
980 .CANCELED => return error.Canceled,
981
976982 .INVAL => |err| return errnoBug(err),
977983 .BADF => |err| return errnoBug(err), // Always a race condition.
978984 .NOMEM => return error.SystemResources,
......@@ -1035,6 +1041,8 @@ fn fileStatPosix(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
10351041 switch (posix.errno(fstat_sym(file.handle, &stat))) {
10361042 .SUCCESS => return statFromPosix(&stat),
10371043 .INTR => continue,
1044 .CANCELED => return error.Canceled,
1045
10381046 .INVAL => |err| return errnoBug(err),
10391047 .BADF => |err| return errnoBug(err),
10401048 .NOMEM => return error.SystemResources,
......@@ -1060,6 +1068,8 @@ fn fileStatLinux(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File
10601068 switch (linux.E.init(rc)) {
10611069 .SUCCESS => return statFromLinux(&statx),
10621070 .INTR => continue,
1071 .CANCELED => return error.Canceled,
1072
10631073 .ACCES => |err| return errnoBug(err),
10641074 .BADF => |err| return errnoBug(err),
10651075 .FAULT => |err| return errnoBug(err),
......@@ -1090,6 +1100,8 @@ fn fileStatWasi(userdata: ?*anyopaque, file: Io.File) Io.File.StatError!Io.File.
10901100 switch (std.os.wasi.fd_filestat_get(file.handle, &stat)) {
10911101 .SUCCESS => return statFromWasi(&stat),
10921102 .INTR => continue,
1103 .CANCELED => return error.Canceled,
1104
10931105 .INVAL => |err| return errnoBug(err),
10941106 .BADF => |err| return errnoBug(err),
10951107 .NOMEM => return error.SystemResources,
......@@ -1253,6 +1265,7 @@ fn dirCreateFilePosix(
12531265 switch (posix.errno(rc)) {
12541266 .SUCCESS => break @intCast(rc),
12551267 .INTR => continue,
1268 .CANCELED => return error.Canceled,
12561269
12571270 .FAULT => |err| return errnoBug(err),
12581271 .INVAL => return error.BadPathName,
......@@ -1296,6 +1309,7 @@ fn dirCreateFilePosix(
12961309 switch (posix.errno(posix.system.flock(fd, lock_flags))) {
12971310 .SUCCESS => break,
12981311 .INTR => continue,
1312 .CANCELED => return error.Canceled,
12991313
13001314 .BADF => |err| return errnoBug(err),
13011315 .INVAL => |err| return errnoBug(err), // invalid parameters
......@@ -1314,6 +1328,7 @@ fn dirCreateFilePosix(
13141328 switch (posix.errno(rc)) {
13151329 .SUCCESS => break @intCast(rc),
13161330 .INTR => continue,
1331 .CANCELED => return error.Canceled,
13171332 else => |err| return posix.unexpectedErrno(err),
13181333 }
13191334 };
......@@ -1323,6 +1338,7 @@ fn dirCreateFilePosix(
13231338 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFL, fl_flags))) {
13241339 .SUCCESS => break,
13251340 .INTR => continue,
1341 .CANCELED => return error.Canceled,
13261342 else => |err| return posix.unexpectedErrno(err),
13271343 }
13281344 }
......@@ -1383,6 +1399,7 @@ fn dirOpenFile(
13831399 switch (posix.errno(rc)) {
13841400 .SUCCESS => break @intCast(rc),
13851401 .INTR => continue,
1402 .CANCELED => return error.Canceled,
13861403
13871404 .FAULT => |err| return errnoBug(err),
13881405 .INVAL => return error.BadPathName,
......@@ -1426,6 +1443,7 @@ fn dirOpenFile(
14261443 switch (posix.errno(posix.system.flock(fd, lock_flags))) {
14271444 .SUCCESS => break,
14281445 .INTR => continue,
1446 .CANCELED => return error.Canceled,
14291447
14301448 .BADF => |err| return errnoBug(err),
14311449 .INVAL => |err| return errnoBug(err), // invalid parameters
......@@ -1444,6 +1462,7 @@ fn dirOpenFile(
14441462 switch (posix.errno(rc)) {
14451463 .SUCCESS => break @intCast(rc),
14461464 .INTR => continue,
1465 .CANCELED => return error.Canceled,
14471466 else => |err| return posix.unexpectedErrno(err),
14481467 }
14491468 };
......@@ -1453,6 +1472,7 @@ fn dirOpenFile(
14531472 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFL, fl_flags))) {
14541473 .SUCCESS => break,
14551474 .INTR => continue,
1475 .CANCELED => return error.Canceled,
14561476 else => |err| return posix.unexpectedErrno(err),
14571477 }
14581478 }
......@@ -1526,6 +1546,8 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File
15261546 switch (std.os.wasi.fd_read(file.handle, dest.ptr, dest.len, &nread)) {
15271547 .SUCCESS => return nread,
15281548 .INTR => continue,
1549 .CANCELED => return error.Canceled,
1550
15291551 .INVAL => |err| return errnoBug(err),
15301552 .FAULT => |err| return errnoBug(err),
15311553 .BADF => |err| return errnoBug(err),
......@@ -1547,6 +1569,8 @@ fn fileReadStreaming(userdata: ?*anyopaque, file: Io.File, data: [][]u8) Io.File
15471569 switch (posix.errno(rc)) {
15481570 .SUCCESS => return @intCast(rc),
15491571 .INTR => continue,
1572 .CANCELED => return error.Canceled,
1573
15501574 .INVAL => |err| return errnoBug(err),
15511575 .FAULT => |err| return errnoBug(err),
15521576 .SRCH => return error.ProcessNotFound,
......@@ -1647,6 +1671,8 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset
16471671 switch (std.os.wasi.fd_pread(file.handle, dest.ptr, dest.len, offset, &nread)) {
16481672 .SUCCESS => return nread,
16491673 .INTR => continue,
1674 .CANCELED => return error.Canceled,
1675
16501676 .INVAL => |err| return errnoBug(err),
16511677 .FAULT => |err| return errnoBug(err),
16521678 .AGAIN => |err| return errnoBug(err),
......@@ -1672,6 +1698,8 @@ fn fileReadPositional(userdata: ?*anyopaque, file: Io.File, data: [][]u8, offset
16721698 switch (posix.errno(rc)) {
16731699 .SUCCESS => return @bitCast(rc),
16741700 .INTR => continue,
1701 .CANCELED => return error.Canceled,
1702
16751703 .INVAL => |err| return errnoBug(err),
16761704 .FAULT => |err| return errnoBug(err),
16771705 .SRCH => return error.ProcessNotFound,
......@@ -1711,6 +1739,8 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
17111739 switch (posix.errno(posix.system.llseek(fd, offset, &result, posix.SEEK.SET))) {
17121740 .SUCCESS => return,
17131741 .INTR => continue,
1742 .CANCELED => return error.Canceled,
1743
17141744 .BADF => |err| return errnoBug(err), // Always a race condition.
17151745 .INVAL => return error.Unseekable,
17161746 .OVERFLOW => return error.Unseekable,
......@@ -1731,6 +1761,8 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
17311761 switch (std.os.wasi.fd_seek(fd, @bitCast(offset), .SET, &new_offset)) {
17321762 .SUCCESS => return,
17331763 .INTR => continue,
1764 .CANCELED => return error.Canceled,
1765
17341766 .BADF => |err| return errnoBug(err), // Always a race condition.
17351767 .INVAL => return error.Unseekable,
17361768 .OVERFLOW => return error.Unseekable,
......@@ -1748,6 +1780,8 @@ fn fileSeekTo(userdata: ?*anyopaque, file: Io.File, offset: u64) Io.File.SeekErr
17481780 switch (posix.errno(lseek_sym(fd, @bitCast(offset), posix.SEEK.SET))) {
17491781 .SUCCESS => return,
17501782 .INTR => continue,
1783 .CANCELED => return error.Canceled,
1784
17511785 .BADF => |err| return errnoBug(err), // Always a race condition.
17521786 .INVAL => return error.Unseekable,
17531787 .OVERFLOW => return error.Unseekable,
......@@ -1845,6 +1879,7 @@ fn sleepLinux(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
18451879 } }, &timespec, &timespec))) {
18461880 .SUCCESS => return,
18471881 .INTR => continue,
1882 .CANCELED => return error.Canceled,
18481883 .INVAL => return error.UnsupportedClock,
18491884 else => |err| return posix.unexpectedErrno(err),
18501885 }
......@@ -1907,6 +1942,7 @@ fn sleepPosix(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
19071942 try t.checkCancel();
19081943 switch (posix.errno(posix.system.nanosleep(&timespec, &timespec))) {
19091944 .INTR => continue,
1945 .CANCELED => return error.Canceled,
19101946 else => return, // This prong handles success as well as unexpected errors.
19111947 }
19121948 }
......@@ -2024,6 +2060,8 @@ fn posixBindUnix(t: *Threaded, fd: posix.socket_t, addr: *const posix.sockaddr,
20242060 switch (posix.errno(posix.system.bind(fd, addr, addr_len))) {
20252061 .SUCCESS => break,
20262062 .INTR => continue,
2063 .CANCELED => return error.Canceled,
2064
20272065 .ACCES => return error.AccessDenied,
20282066 .ADDRINUSE => return error.AddressInUse,
20292067 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
......@@ -2052,6 +2090,8 @@ fn posixBind(t: *Threaded, socket_fd: posix.socket_t, addr: *const posix.sockadd
20522090 switch (posix.errno(posix.system.bind(socket_fd, addr, addr_len))) {
20532091 .SUCCESS => break,
20542092 .INTR => continue,
2093 .CANCELED => return error.Canceled,
2094
20552095 .ADDRINUSE => return error.AddressInUse,
20562096 .BADF => |err| return errnoBug(err), // always a race condition if this error is returned
20572097 .INVAL => |err| return errnoBug(err), // invalid parameters
......@@ -2071,6 +2111,8 @@ fn posixConnect(t: *Threaded, socket_fd: posix.socket_t, addr: *const posix.sock
20712111 switch (posix.errno(posix.system.connect(socket_fd, addr, addr_len))) {
20722112 .SUCCESS => return,
20732113 .INTR => continue,
2114 .CANCELED => return error.Canceled,
2115
20742116 .ADDRNOTAVAIL => return error.AddressUnavailable,
20752117 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
20762118 .AGAIN, .INPROGRESS => return error.WouldBlock,
......@@ -2100,6 +2142,7 @@ fn posixConnectUnix(t: *Threaded, fd: posix.socket_t, addr: *const posix.sockadd
21002142 switch (posix.errno(posix.system.connect(fd, addr, addr_len))) {
21012143 .SUCCESS => return,
21022144 .INTR => continue,
2145 .CANCELED => return error.Canceled,
21032146
21042147 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
21052148 .AGAIN => return error.WouldBlock,
......@@ -2129,6 +2172,8 @@ fn posixGetSockName(t: *Threaded, socket_fd: posix.fd_t, addr: *posix.sockaddr,
21292172 switch (posix.errno(posix.system.getsockname(socket_fd, addr, addr_len))) {
21302173 .SUCCESS => break,
21312174 .INTR => continue,
2175 .CANCELED => return error.Canceled,
2176
21322177 .BADF => |err| return errnoBug(err), // always a race condition
21332178 .FAULT => |err| return errnoBug(err),
21342179 .INVAL => |err| return errnoBug(err), // invalid parameters
......@@ -2146,6 +2191,8 @@ fn setSocketOption(t: *Threaded, fd: posix.fd_t, level: i32, opt_name: u32, opti
21462191 switch (posix.errno(posix.system.setsockopt(fd, level, opt_name, o.ptr, @intCast(o.len)))) {
21472192 .SUCCESS => return,
21482193 .INTR => continue,
2194 .CANCELED => return error.Canceled,
2195
21492196 .BADF => |err| return errnoBug(err), // always a race condition
21502197 .NOTSOCK => |err| return errnoBug(err), // always a race condition
21512198 .INVAL => |err| return errnoBug(err),
......@@ -2245,12 +2292,15 @@ fn openSocketPosix(
22452292 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
22462293 .SUCCESS => break,
22472294 .INTR => continue,
2295 .CANCELED => return error.Canceled,
22482296 else => |err| return posix.unexpectedErrno(err),
22492297 }
22502298 };
22512299 break fd;
22522300 },
22532301 .INTR => continue,
2302 .CANCELED => return error.Canceled,
2303
22542304 .AFNOSUPPORT => return error.AddressFamilyUnsupported,
22552305 .INVAL => return error.ProtocolUnsupportedBySystem,
22562306 .MFILE => return error.ProcessFdQuotaExceeded,
......@@ -2294,12 +2344,14 @@ fn netAcceptPosix(userdata: ?*anyopaque, listen_fd: net.Socket.Handle) net.Serve
22942344 switch (posix.errno(posix.system.fcntl(fd, posix.F.SETFD, @as(usize, posix.FD_CLOEXEC)))) {
22952345 .SUCCESS => break,
22962346 .INTR => continue,
2347 .CANCELED => return error.Canceled,
22972348 else => |err| return posix.unexpectedErrno(err),
22982349 }
22992350 };
23002351 break fd;
23012352 },
23022353 .INTR => continue,
2354 .CANCELED => return error.Canceled,
23032355 .AGAIN => |err| return errnoBug(err),
23042356 .BADF => |err| return errnoBug(err), // always a race condition
23052357 .CONNABORTED => return error.ConnectionAborted,
......@@ -2343,6 +2395,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
23432395 switch (std.os.wasi.fd_read(fd, dest.ptr, dest.len, &n)) {
23442396 .SUCCESS => return n,
23452397 .INTR => continue,
2398 .CANCELED => return error.Canceled,
23462399
23472400 .INVAL => |err| return errnoBug(err),
23482401 .FAULT => |err| return errnoBug(err),
......@@ -2364,6 +2417,7 @@ fn netReadPosix(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.
23642417 switch (posix.errno(rc)) {
23652418 .SUCCESS => return @intCast(rc),
23662419 .INTR => continue,
2420 .CANCELED => return error.Canceled,
23672421
23682422 .INVAL => |err| return errnoBug(err),
23692423 .FAULT => |err| return errnoBug(err),
......@@ -2464,6 +2518,7 @@ fn netSendOne(
24642518 return;
24652519 },
24662520 .INTR => continue,
2521 .CANCELED => return error.Canceled,
24672522
24682523 .ACCES => return error.AccessDenied,
24692524 .ALREADY => return error.FastOpenAlreadyInProgress,
......@@ -2531,13 +2586,15 @@ fn netSendMany(
25312586 }
25322587 return n;
25332588 },
2589 .INTR => continue,
2590 .CANCELED => return error.Canceled,
2591
25342592 .AGAIN => |err| return errnoBug(err),
25352593 .ALREADY => return error.FastOpenAlreadyInProgress,
25362594 .BADF => |err| return errnoBug(err), // Always a race condition.
25372595 .CONNRESET => return error.ConnectionResetByPeer,
25382596 .DESTADDRREQ => |err| return errnoBug(err), // The socket is not connection-mode, and no peer address is set.
25392597 .FAULT => |err| return errnoBug(err), // An invalid user space address was specified for an argument.
2540 .INTR => continue,
25412598 .INVAL => |err| return errnoBug(err), // Invalid argument passed.
25422599 .ISCONN => |err| return errnoBug(err), // connection-mode socket was connected already but a recipient was specified
25432600 .MSGSIZE => return error.MessageOversize,
......@@ -2654,6 +2711,7 @@ fn netReceive(
26542711 continue :recv;
26552712 },
26562713 .INTR => continue,
2714 .CANCELED => return .{ error.Canceled, message_i },
26572715
26582716 .FAULT => |err| return .{ errnoBug(err), message_i },
26592717 .INVAL => |err| return .{ errnoBug(err), message_i },
......@@ -2662,6 +2720,7 @@ fn netReceive(
26622720 }
26632721 },
26642722 .INTR => continue,
2723 .CANCELED => return .{ error.Canceled, message_i },
26652724
26662725 .BADF => |err| return .{ errnoBug(err), message_i },
26672726 .NFILE => return .{ error.SystemFdQuotaExceeded, message_i },
......@@ -2780,6 +2839,8 @@ fn netInterfaceNameResolve(
27802839 switch (posix.errno(posix.system.ioctl(sock_fd, posix.SIOCGIFINDEX, @intFromPtr(&ifr)))) {
27812840 .SUCCESS => return .{ .index = @bitCast(ifr.ifru.ivalue) },
27822841 .INTR => continue,
2842 .CANCELED => return error.Canceled,
2843
27832844 .INVAL => |err| return errnoBug(err), // Bad parameters.
27842845 .NOTTY => |err| return errnoBug(err),
27852846 .NXIO => |err| return errnoBug(err),
......@@ -2968,6 +3029,7 @@ fn netLookupFallible(
29683029 .NONAME => return error.UnknownHostName,
29693030 .SYSTEM => switch (posix.errno(-1)) {
29703031 .INTR => continue,
3032 .CANCELED => return error.Canceled,
29713033 else => |e| return posix.unexpectedErrno(e),
29723034 },
29733035 else => return error.Unexpected,
......@@ -3754,7 +3816,7 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {
37543816 const status = c.__ulock_wake(flags, ptr, 0);
37553817 if (status >= 0) return;
37563818 switch (@as(c.E, @enumFromInt(-status))) {
3757 .INTR => continue, // spurious wake()
3819 .INTR, .CANCELED => continue, // spurious wake()
37583820 .FAULT => assert(!is_debug), // __ulock_wake doesn't generate EFAULT according to darwin pthread_cond_t
37593821 .NOENT => return, // nothing was woken up
37603822 .ALREADY => assert(!is_debug), // only for UL.Op.WAKE_THREAD