authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-28 05:51:15-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-02-28 05:51:15-08:00
loga1b083b6667bbacc80db485ea97eceb6867cf600
tree2873fefc63d11e3fee3593459dcd9a16c3f7bceb
parent6e078883eebd0532928dba0c70e86a2eee0f246b
parentf446d8e8f9bbfc52e73649b1754dab88d4acfb07
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #19120 from jacobly0/os-cleanup

posix: fix socket fd leak

2 files changed, 163 insertions(+), 212 deletions(-)

lib/std/Target.zig+4-1
...@@ -392,7 +392,10 @@ pub const Os = struct {...@@ -392,7 +392,10 @@ pub const Os = struct {
392392
393 /// Checks if system is guaranteed to be at least `version` or older than `version`.393 /// Checks if system is guaranteed to be at least `version` or older than `version`.
394 /// Returns `null` if a runtime check is required.394 /// Returns `null` if a runtime check is required.
395 pub inline fn isAtLeast(self: Os, comptime tag: Tag, version: anytype) ?bool {395 pub inline fn isAtLeast(self: Os, comptime tag: Tag, version: switch (tag) {
396 else => std.SemanticVersion,
397 .windows => WindowsVersion,
398 }) ?bool {
396 if (self.tag != tag) return false;399 if (self.tag != tag) return false;
397400
398 return switch (tag) {401 return switch (tag) {
lib/std/os.zig+159-211
...@@ -302,7 +302,7 @@ pub fn close(fd: fd_t) void {...@@ -302,7 +302,7 @@ pub fn close(fd: fd_t) void {
302 _ = wasi.fd_close(fd);302 _ = wasi.fd_close(fd);
303 return;303 return;
304 }304 }
305 if (comptime builtin.target.isDarwin()) {305 if (builtin.target.isDarwin()) {
306 // This avoids the EINTR problem.306 // This avoids the EINTR problem.
307 switch (darwin.getErrno(darwin.@"close$NOCANCEL"(fd))) {307 switch (darwin.getErrno(darwin.@"close$NOCANCEL"(fd))) {
308 .BADF => unreachable, // Always a race condition.308 .BADF => unreachable, // Always a race condition.
...@@ -476,7 +476,7 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr...@@ -476,7 +476,7 @@ fn fchmodat2(dirfd: fd_t, path: []const u8, mode: mode_t, flags: u32) FChmodAtEr
476 const rc = system.openat(dirfd, &path_c, .{ .PATH = true, .NOFOLLOW = true, .CLOEXEC = true }, @as(mode_t, 0));476 const rc = system.openat(dirfd, &path_c, .{ .PATH = true, .NOFOLLOW = true, .CLOEXEC = true }, @as(mode_t, 0));
477 switch (system.getErrno(rc)) {477 switch (system.getErrno(rc)) {
478 .SUCCESS => {478 .SUCCESS => {
479 pathfd = @as(fd_t, @intCast(rc));479 pathfd = @intCast(rc);
480 break;480 break;
481 },481 },
482 .INTR => continue,482 .INTR => continue,
...@@ -550,7 +550,7 @@ pub fn fchown(fd: fd_t, owner: ?uid_t, group: ?gid_t) FChownError!void {...@@ -550,7 +550,7 @@ pub fn fchown(fd: fd_t, owner: ?uid_t, group: ?gid_t) FChownError!void {
550 }550 }
551551
552 while (true) {552 while (true) {
553 const res = system.fchown(fd, owner orelse @as(u32, 0) -% 1, group orelse @as(u32, 0) -% 1);553 const res = system.fchown(fd, owner orelse ~@as(uid_t, 0), group orelse ~@as(gid_t, 0));
554554
555 switch (system.getErrno(res)) {555 switch (system.getErrno(res)) {
556 .SUCCESS => return,556 .SUCCESS => return,
...@@ -596,7 +596,7 @@ pub fn reboot(cmd: RebootCommand) RebootError!void {...@@ -596,7 +596,7 @@ pub fn reboot(cmd: RebootCommand) RebootError!void {
596 switch (system.getErrno(linux.reboot(596 switch (system.getErrno(linux.reboot(
597 .MAGIC1,597 .MAGIC1,
598 .MAGIC2,598 .MAGIC2,
599 @as(linux.LINUX_REBOOT.CMD, cmd),599 cmd,
600 switch (cmd) {600 switch (cmd) {
601 .RESTART2 => |s| s,601 .RESTART2 => |s| s,
602 else => null,602 else => null,
...@@ -639,27 +639,27 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {...@@ -639,27 +639,27 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
639 std.c.versionCheck(std.SemanticVersion{ .major = 2, .minor = 25, .patch = 0 });639 std.c.versionCheck(std.SemanticVersion{ .major = 2, .minor = 25, .patch = 0 });
640640
641 while (buf.len != 0) {641 while (buf.len != 0) {
642 const res = if (use_c) blk: {642 const num_read: usize, const err = if (use_c) res: {
643 const rc = std.c.getrandom(buf.ptr, buf.len, 0);643 const rc = std.c.getrandom(buf.ptr, buf.len, 0);
644 break :blk .{644 break :res .{
645 .num_read = @as(usize, @bitCast(rc)),645 @bitCast(rc),
646 .err = std.c.getErrno(rc),646 std.c.getErrno(rc),
647 };647 };
648 } else blk: {648 } else res: {
649 const rc = linux.getrandom(buf.ptr, buf.len, 0);649 const rc = linux.getrandom(buf.ptr, buf.len, 0);
650 break :blk .{650 break :res .{
651 .num_read = rc,651 rc,
652 .err = linux.getErrno(rc),652 linux.getErrno(rc),
653 };653 };
654 };654 };
655655
656 switch (res.err) {656 switch (err) {
657 .SUCCESS => buf = buf[res.num_read..],657 .SUCCESS => buf = buf[num_read..],
658 .INVAL => unreachable,658 .INVAL => unreachable,
659 .FAULT => unreachable,659 .FAULT => unreachable,
660 .INTR => continue,660 .INTR => continue,
661 .NOSYS => return getRandomBytesDevURandom(buf),661 .NOSYS => return getRandomBytesDevURandom(buf),
662 else => return unexpectedErrno(res.err),662 else => return unexpectedErrno(err),
663 }663 }
664 }664 }
665 return;665 return;
...@@ -818,10 +818,10 @@ pub fn exit(status: u8) noreturn {...@@ -818,10 +818,10 @@ pub fn exit(status: u8) noreturn {
818 // exit() is only available if exitBootServices() has not been called yet.818 // exit() is only available if exitBootServices() has not been called yet.
819 // This call to exit should not fail, so we don't care about its return value.819 // This call to exit should not fail, so we don't care about its return value.
820 if (uefi.system_table.boot_services) |bs| {820 if (uefi.system_table.boot_services) |bs| {
821 _ = bs.exit(uefi.handle, @as(uefi.Status, @enumFromInt(status)), 0, null);821 _ = bs.exit(uefi.handle, @enumFromInt(status), 0, null);
822 }822 }
823 // If we can't exit, reboot the system instead.823 // If we can't exit, reboot the system instead.
824 uefi.system_table.runtime_services.resetSystem(uefi.tables.ResetType.ResetCold, @as(uefi.Status, @enumFromInt(status)), 0, null);824 uefi.system_table.runtime_services.resetSystem(.ResetCold, @enumFromInt(status), 0, null);
825 }825 }
826 system.exit(status);826 system.exit(status);
827}827}
...@@ -893,12 +893,10 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {...@@ -893,12 +893,10 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
893 .macos, .ios, .watchos, .tvos => math.maxInt(i32),893 .macos, .ios, .watchos, .tvos => math.maxInt(i32),
894 else => math.maxInt(isize),894 else => math.maxInt(isize),
895 };895 };
896 const adjusted_len = @min(max_count, buf.len);
897
898 while (true) {896 while (true) {
899 const rc = system.read(fd, buf.ptr, adjusted_len);897 const rc = system.read(fd, buf.ptr, @min(buf.len, max_count));
900 switch (errno(rc)) {898 switch (errno(rc)) {
901 .SUCCESS => return @as(usize, @intCast(rc)),899 .SUCCESS => return @intCast(rc),
902 .INTR => continue,900 .INTR => continue,
903 .INVAL => unreachable,901 .INVAL => unreachable,
904 .FAULT => unreachable,902 .FAULT => unreachable,
...@@ -932,7 +930,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {...@@ -932,7 +930,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
932pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {930pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {
933 if (builtin.os.tag == .windows) {931 if (builtin.os.tag == .windows) {
934 // TODO improve this to use ReadFileScatter932 // TODO improve this to use ReadFileScatter
935 if (iov.len == 0) return @as(usize, 0);933 if (iov.len == 0) return 0;
936 const first = iov[0];934 const first = iov[0];
937 return read(fd, first.iov_base[0..first.iov_len]);935 return read(fd, first.iov_base[0..first.iov_len]);
938 }936 }
...@@ -956,12 +954,11 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {...@@ -956,12 +954,11 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize {
956 else => |err| return unexpectedErrno(err),954 else => |err| return unexpectedErrno(err),
957 }955 }
958 }956 }
959 const iov_count = math.cast(u31, iov.len) orelse math.maxInt(u31);957
960 while (true) {958 while (true) {
961 // TODO handle the case when iov_len is too large and get rid of this @intCast959 const rc = system.readv(fd, iov.ptr, @min(iov.len, IOV_MAX));
962 const rc = system.readv(fd, iov.ptr, iov_count);
963 switch (errno(rc)) {960 switch (errno(rc)) {
964 .SUCCESS => return @as(usize, @intCast(rc)),961 .SUCCESS => return @intCast(rc),
965 .INTR => continue,962 .INTR => continue,
966 .INVAL => unreachable,963 .INVAL => unreachable,
967 .FAULT => unreachable,964 .FAULT => unreachable,
...@@ -1035,15 +1032,12 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {...@@ -1035,15 +1032,12 @@ pub fn pread(fd: fd_t, buf: []u8, offset: u64) PReadError!usize {
1035 .macos, .ios, .watchos, .tvos => math.maxInt(i32),1032 .macos, .ios, .watchos, .tvos => math.maxInt(i32),
1036 else => math.maxInt(isize),1033 else => math.maxInt(isize),
1037 };1034 };
1038 const adjusted_len = @min(max_count, buf.len);
10391035
1040 const pread_sym = if (lfs64_abi) system.pread64 else system.pread;1036 const pread_sym = if (lfs64_abi) system.pread64 else system.pread;
1041
1042 const ioffset = @as(i64, @bitCast(offset)); // the OS treats this as unsigned
1043 while (true) {1037 while (true) {
1044 const rc = pread_sym(fd, buf.ptr, adjusted_len, ioffset);1038 const rc = pread_sym(fd, buf.ptr, @min(buf.len, max_count), @bitCast(offset));
1045 switch (errno(rc)) {1039 switch (errno(rc)) {
1046 .SUCCESS => return @as(usize, @intCast(rc)),1040 .SUCCESS => return @intCast(rc),
1047 .INTR => continue,1041 .INTR => continue,
1048 .INVAL => unreachable,1042 .INVAL => unreachable,
1049 .FAULT => unreachable,1043 .FAULT => unreachable,
...@@ -1078,7 +1072,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {...@@ -1078,7 +1072,7 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
1078 if (builtin.os.tag == .windows) {1072 if (builtin.os.tag == .windows) {
1079 var io_status_block: windows.IO_STATUS_BLOCK = undefined;1073 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
1080 var eof_info = windows.FILE_END_OF_FILE_INFORMATION{1074 var eof_info = windows.FILE_END_OF_FILE_INFORMATION{
1081 .EndOfFile = @as(windows.LARGE_INTEGER, @bitCast(length)),1075 .EndOfFile = @bitCast(length),
1082 };1076 };
10831077
1084 const rc = windows.ntdll.NtSetInformationFile(1078 const rc = windows.ntdll.NtSetInformationFile(
...@@ -1111,11 +1105,9 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {...@@ -1111,11 +1105,9 @@ pub fn ftruncate(fd: fd_t, length: u64) TruncateError!void {
1111 }1105 }
1112 }1106 }
11131107
1108 const ftruncate_sym = if (lfs64_abi) system.ftruncate64 else system.ftruncate;
1114 while (true) {1109 while (true) {
1115 const ftruncate_sym = if (lfs64_abi) system.ftruncate64 else system.ftruncate;1110 switch (errno(ftruncate_sym(fd, @bitCast(length)))) {
1116
1117 const ilen = @as(i64, @bitCast(length)); // the OS treats this as unsigned
1118 switch (errno(ftruncate_sym(fd, ilen))) {
1119 .SUCCESS => return,1111 .SUCCESS => return,
1120 .INTR => continue,1112 .INTR => continue,
1121 .FBIG => return error.FileTooBig,1113 .FBIG => return error.FileTooBig,
...@@ -1178,15 +1170,11 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {...@@ -1178,15 +1170,11 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
1178 }1170 }
1179 }1171 }
11801172
1181 const iov_count = math.cast(u31, iov.len) orelse math.maxInt(u31);
1182
1183 const preadv_sym = if (lfs64_abi) system.preadv64 else system.preadv;1173 const preadv_sym = if (lfs64_abi) system.preadv64 else system.preadv;
1184
1185 const ioffset = @as(i64, @bitCast(offset)); // the OS treats this as unsigned
1186 while (true) {1174 while (true) {
1187 const rc = preadv_sym(fd, iov.ptr, iov_count, ioffset);1175 const rc = preadv_sym(fd, iov.ptr, @min(iov.len, IOV_MAX), @bitCast(offset));
1188 switch (errno(rc)) {1176 switch (errno(rc)) {
1189 .SUCCESS => return @as(usize, @bitCast(rc)),1177 .SUCCESS => return @bitCast(rc),
1190 .INTR => continue,1178 .INTR => continue,
1191 .INVAL => unreachable,1179 .INVAL => unreachable,
1192 .FAULT => unreachable,1180 .FAULT => unreachable,
...@@ -1293,12 +1281,10 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize {...@@ -1293,12 +1281,10 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize {
1293 .macos, .ios, .watchos, .tvos => math.maxInt(i32),1281 .macos, .ios, .watchos, .tvos => math.maxInt(i32),
1294 else => math.maxInt(isize),1282 else => math.maxInt(isize),
1295 };1283 };
1296 const adjusted_len = @min(max_count, bytes.len);
1297
1298 while (true) {1284 while (true) {
1299 const rc = system.write(fd, bytes.ptr, adjusted_len);1285 const rc = system.write(fd, bytes.ptr, @min(bytes.len, max_count));
1300 switch (errno(rc)) {1286 switch (errno(rc)) {
1301 .SUCCESS => return @as(usize, @intCast(rc)),1287 .SUCCESS => return @intCast(rc),
1302 .INTR => continue,1288 .INTR => continue,
1303 .INVAL => return error.InvalidArgument,1289 .INVAL => return error.InvalidArgument,
1304 .FAULT => unreachable,1290 .FAULT => unreachable,
...@@ -1342,7 +1328,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize {...@@ -1342,7 +1328,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!usize {
1342pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize {1328pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize {
1343 if (builtin.os.tag == .windows) {1329 if (builtin.os.tag == .windows) {
1344 // TODO improve this to use WriteFileScatter1330 // TODO improve this to use WriteFileScatter
1345 if (iov.len == 0) return @as(usize, 0);1331 if (iov.len == 0) return 0;
1346 const first = iov[0];1332 const first = iov[0];
1347 return write(fd, first.iov_base[0..first.iov_len]);1333 return write(fd, first.iov_base[0..first.iov_len]);
1348 }1334 }
...@@ -1367,11 +1353,10 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize {...@@ -1367,11 +1353,10 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize {
1367 }1353 }
1368 }1354 }
13691355
1370 const iov_count = if (iov.len > IOV_MAX) IOV_MAX else @as(u31, @intCast(iov.len));
1371 while (true) {1356 while (true) {
1372 const rc = system.writev(fd, iov.ptr, iov_count);1357 const rc = system.writev(fd, iov.ptr, @min(iov.len, IOV_MAX));
1373 switch (errno(rc)) {1358 switch (errno(rc)) {
1374 .SUCCESS => return @as(usize, @intCast(rc)),1359 .SUCCESS => return @intCast(rc),
1375 .INTR => continue,1360 .INTR => continue,
1376 .INVAL => return error.InvalidArgument,1361 .INVAL => return error.InvalidArgument,
1377 .FAULT => unreachable,1362 .FAULT => unreachable,
...@@ -1455,15 +1440,12 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {...@@ -1455,15 +1440,12 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
1455 .macos, .ios, .watchos, .tvos => math.maxInt(i32),1440 .macos, .ios, .watchos, .tvos => math.maxInt(i32),
1456 else => math.maxInt(isize),1441 else => math.maxInt(isize),
1457 };1442 };
1458 const adjusted_len = @min(max_count, bytes.len);
14591443
1460 const pwrite_sym = if (lfs64_abi) system.pwrite64 else system.pwrite;1444 const pwrite_sym = if (lfs64_abi) system.pwrite64 else system.pwrite;
1461
1462 const ioffset = @as(i64, @bitCast(offset)); // the OS treats this as unsigned
1463 while (true) {1445 while (true) {
1464 const rc = pwrite_sym(fd, bytes.ptr, adjusted_len, ioffset);1446 const rc = pwrite_sym(fd, bytes.ptr, @min(bytes.len, max_count), @bitCast(offset));
1465 switch (errno(rc)) {1447 switch (errno(rc)) {
1466 .SUCCESS => return @as(usize, @intCast(rc)),1448 .SUCCESS => return @intCast(rc),
1467 .INTR => continue,1449 .INTR => continue,
1468 .INVAL => return error.InvalidArgument,1450 .INVAL => return error.InvalidArgument,
1469 .FAULT => unreachable,1451 .FAULT => unreachable,
...@@ -1515,7 +1497,7 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz...@@ -1515,7 +1497,7 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz
1515 if (have_pwrite_but_not_pwritev) {1497 if (have_pwrite_but_not_pwritev) {
1516 // We could loop here; but proper usage of `pwritev` must handle partial writes anyway.1498 // We could loop here; but proper usage of `pwritev` must handle partial writes anyway.
1517 // So we simply write the first vector only.1499 // So we simply write the first vector only.
1518 if (iov.len == 0) return @as(usize, 0);1500 if (iov.len == 0) return 0;
1519 const first = iov[0];1501 const first = iov[0];
1520 return pwrite(fd, first.iov_base[0..first.iov_len], offset);1502 return pwrite(fd, first.iov_base[0..first.iov_len], offset);
1521 }1503 }
...@@ -1544,13 +1526,10 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz...@@ -1544,13 +1526,10 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz
1544 }1526 }
15451527
1546 const pwritev_sym = if (lfs64_abi) system.pwritev64 else system.pwritev;1528 const pwritev_sym = if (lfs64_abi) system.pwritev64 else system.pwritev;
1547
1548 const iov_count = if (iov.len > IOV_MAX) IOV_MAX else @as(u31, @intCast(iov.len));
1549 const ioffset = @as(i64, @bitCast(offset)); // the OS treats this as unsigned
1550 while (true) {1529 while (true) {
1551 const rc = pwritev_sym(fd, iov.ptr, iov_count, ioffset);1530 const rc = pwritev_sym(fd, iov.ptr, @min(iov.len, IOV_MAX), @bitCast(offset));
1552 switch (errno(rc)) {1531 switch (errno(rc)) {
1553 .SUCCESS => return @as(usize, @intCast(rc)),1532 .SUCCESS => return @intCast(rc),
1554 .INTR => continue,1533 .INTR => continue,
1555 .INVAL => return error.InvalidArgument,1534 .INVAL => return error.InvalidArgument,
1556 .FAULT => unreachable,1535 .FAULT => unreachable,
...@@ -1666,11 +1645,10 @@ pub fn openZ(file_path: [*:0]const u8, flags: O, perm: mode_t) OpenError!fd_t {...@@ -1666,11 +1645,10 @@ pub fn openZ(file_path: [*:0]const u8, flags: O, perm: mode_t) OpenError!fd_t {
1666 }1645 }
16671646
1668 const open_sym = if (lfs64_abi) system.open64 else system.open;1647 const open_sym = if (lfs64_abi) system.open64 else system.open;
1669
1670 while (true) {1648 while (true) {
1671 const rc = open_sym(file_path, flags, perm);1649 const rc = open_sym(file_path, flags, perm);
1672 switch (errno(rc)) {1650 switch (errno(rc)) {
1673 .SUCCESS => return @as(fd_t, @intCast(rc)),1651 .SUCCESS => return @intCast(rc),
1674 .INTR => continue,1652 .INTR => continue,
16751653
1676 .FAULT => unreachable,1654 .FAULT => unreachable,
...@@ -1863,11 +1841,10 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: O, mode: mode_t) O...@@ -1863,11 +1841,10 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: O, mode: mode_t) O
1863 }1841 }
18641842
1865 const openat_sym = if (lfs64_abi) system.openat64 else system.openat;1843 const openat_sym = if (lfs64_abi) system.openat64 else system.openat;
1866
1867 while (true) {1844 while (true) {
1868 const rc = openat_sym(dir_fd, file_path, flags, mode);1845 const rc = openat_sym(dir_fd, file_path, flags, mode);
1869 switch (errno(rc)) {1846 switch (errno(rc)) {
1870 .SUCCESS => return @as(fd_t, @intCast(rc)),1847 .SUCCESS => return @intCast(rc),
1871 .INTR => continue,1848 .INTR => continue,
18721849
1873 .FAULT => unreachable,1850 .FAULT => unreachable,
...@@ -1900,7 +1877,7 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: O, mode: mode_t) O...@@ -1900,7 +1877,7 @@ pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: O, mode: mode_t) O
1900pub fn dup(old_fd: fd_t) !fd_t {1877pub fn dup(old_fd: fd_t) !fd_t {
1901 const rc = system.dup(old_fd);1878 const rc = system.dup(old_fd);
1902 return switch (errno(rc)) {1879 return switch (errno(rc)) {
1903 .SUCCESS => return @as(fd_t, @intCast(rc)),1880 .SUCCESS => return @intCast(rc),
1904 .MFILE => error.ProcessFdQuotaExceeded,1881 .MFILE => error.ProcessFdQuotaExceeded,
1905 .BADF => unreachable, // invalid file descriptor1882 .BADF => unreachable, // invalid file descriptor
1906 else => |err| return unexpectedErrno(err),1883 else => |err| return unexpectedErrno(err),
...@@ -2144,11 +2121,11 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {...@@ -2144,11 +2121,11 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
2144 return result;2121 return result;
2145 }2122 }
21462123
2147 const err = if (builtin.link_libc) blk: {2124 const err: E = if (builtin.link_libc) err: {
2148 const c_err = if (std.c.getcwd(out_buffer.ptr, out_buffer.len)) |_| 0 else std.c._errno().*;2125 const c_err = if (std.c.getcwd(out_buffer.ptr, out_buffer.len)) |_| 0 else std.c._errno().*;
2149 break :blk @as(E, @enumFromInt(c_err));2126 break :err @enumFromInt(c_err);
2150 } else blk: {2127 } else err: {
2151 break :blk errno(system.getcwd(out_buffer.ptr, out_buffer.len));2128 break :err errno(system.getcwd(out_buffer.ptr, out_buffer.len));
2152 };2129 };
2153 switch (err) {2130 switch (err) {
2154 .SUCCESS => return mem.sliceTo(out_buffer, 0),2131 .SUCCESS => return mem.sliceTo(out_buffer, 0),
...@@ -2880,13 +2857,13 @@ pub fn renameatW(...@@ -2880,13 +2857,13 @@ pub fn renameatW(
2880 // supported in order to avoid either (1) using a redundant call that we can know in advance will return2857 // supported in order to avoid either (1) using a redundant call that we can know in advance will return
2881 // STATUS_NOT_SUPPORTED or (2) only setting IGNORE_READONLY_ATTRIBUTE when >= rs52858 // STATUS_NOT_SUPPORTED or (2) only setting IGNORE_READONLY_ATTRIBUTE when >= rs5
2882 // and therefore having different behavior when the Windows version is >= rs1 but < rs5.2859 // and therefore having different behavior when the Windows version is >= rs1 but < rs5.
2883 if (comptime builtin.target.os.version_range.windows.min.isAtLeast(.win10_rs5)) {2860 if (builtin.target.os.isAtLeast(.windows, .win10_rs5) orelse false) {
2884 const struct_buf_len = @sizeOf(windows.FILE_RENAME_INFORMATION_EX) + (MAX_PATH_BYTES - 1);2861 const struct_buf_len = @sizeOf(windows.FILE_RENAME_INFORMATION_EX) + (MAX_PATH_BYTES - 1);
2885 var rename_info_buf: [struct_buf_len]u8 align(@alignOf(windows.FILE_RENAME_INFORMATION_EX)) = undefined;2862 var rename_info_buf: [struct_buf_len]u8 align(@alignOf(windows.FILE_RENAME_INFORMATION_EX)) = undefined;
2886 const struct_len = @sizeOf(windows.FILE_RENAME_INFORMATION_EX) - 1 + new_path_w.len * 2;2863 const struct_len = @sizeOf(windows.FILE_RENAME_INFORMATION_EX) - 1 + new_path_w.len * 2;
2887 if (struct_len > struct_buf_len) return error.NameTooLong;2864 if (struct_len > struct_buf_len) return error.NameTooLong;
28882865
2889 const rename_info = @as(*windows.FILE_RENAME_INFORMATION_EX, @ptrCast(&rename_info_buf));2866 const rename_info: *windows.FILE_RENAME_INFORMATION_EX = @ptrCast(&rename_info_buf);
2890 var io_status_block: windows.IO_STATUS_BLOCK = undefined;2867 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
28912868
2892 var flags: windows.ULONG = windows.FILE_RENAME_POSIX_SEMANTICS | windows.FILE_RENAME_IGNORE_READONLY_ATTRIBUTE;2869 var flags: windows.ULONG = windows.FILE_RENAME_POSIX_SEMANTICS | windows.FILE_RENAME_IGNORE_READONLY_ATTRIBUTE;
...@@ -2897,7 +2874,7 @@ pub fn renameatW(...@@ -2897,7 +2874,7 @@ pub fn renameatW(
2897 .FileNameLength = @intCast(new_path_w.len * 2), // already checked error.NameTooLong2874 .FileNameLength = @intCast(new_path_w.len * 2), // already checked error.NameTooLong
2898 .FileName = undefined,2875 .FileName = undefined,
2899 };2876 };
2900 @memcpy(@as([*]u16, &rename_info.FileName)[0..new_path_w.len], new_path_w);2877 @memcpy((&rename_info.FileName).ptr, new_path_w);
2901 rc = windows.ntdll.NtSetInformationFile(2878 rc = windows.ntdll.NtSetInformationFile(
2902 src_fd,2879 src_fd,
2903 &io_status_block,2880 &io_status_block,
...@@ -2923,7 +2900,7 @@ pub fn renameatW(...@@ -2923,7 +2900,7 @@ pub fn renameatW(
2923 const struct_len = @sizeOf(windows.FILE_RENAME_INFORMATION) - 1 + new_path_w.len * 2;2900 const struct_len = @sizeOf(windows.FILE_RENAME_INFORMATION) - 1 + new_path_w.len * 2;
2924 if (struct_len > struct_buf_len) return error.NameTooLong;2901 if (struct_len > struct_buf_len) return error.NameTooLong;
29252902
2926 const rename_info = @as(*windows.FILE_RENAME_INFORMATION, @ptrCast(&rename_info_buf));2903 const rename_info: *windows.FILE_RENAME_INFORMATION = @ptrCast(&rename_info_buf);
2927 var io_status_block: windows.IO_STATUS_BLOCK = undefined;2904 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
29282905
2929 rename_info.* = .{2906 rename_info.* = .{
...@@ -2932,7 +2909,7 @@ pub fn renameatW(...@@ -2932,7 +2909,7 @@ pub fn renameatW(
2932 .FileNameLength = @intCast(new_path_w.len * 2), // already checked error.NameTooLong2909 .FileNameLength = @intCast(new_path_w.len * 2), // already checked error.NameTooLong
2933 .FileName = undefined,2910 .FileName = undefined,
2934 };2911 };
2935 @memcpy(@as([*]u16, &rename_info.FileName)[0..new_path_w.len], new_path_w);2912 @memcpy((&rename_info.FileName).ptr, new_path_w);
29362913
2937 rc =2914 rc =
2938 windows.ntdll.NtSetInformationFile(2915 windows.ntdll.NtSetInformationFile(
...@@ -3380,7 +3357,7 @@ pub fn readlinkZ(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8...@@ -3380,7 +3357,7 @@ pub fn readlinkZ(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8
3380 }3357 }
3381 const rc = system.readlink(file_path, out_buffer.ptr, out_buffer.len);3358 const rc = system.readlink(file_path, out_buffer.ptr, out_buffer.len);
3382 switch (errno(rc)) {3359 switch (errno(rc)) {
3383 .SUCCESS => return out_buffer[0..@as(usize, @bitCast(rc))],3360 .SUCCESS => return out_buffer[0..@bitCast(rc)],
3384 .ACCES => return error.AccessDenied,3361 .ACCES => return error.AccessDenied,
3385 .FAULT => unreachable,3362 .FAULT => unreachable,
3386 .INVAL => return error.NotLink,3363 .INVAL => return error.NotLink,
...@@ -3458,7 +3435,7 @@ pub fn readlinkatZ(dirfd: fd_t, file_path: [*:0]const u8, out_buffer: []u8) Read...@@ -3458,7 +3435,7 @@ pub fn readlinkatZ(dirfd: fd_t, file_path: [*:0]const u8, out_buffer: []u8) Read
3458 }3435 }
3459 const rc = system.readlinkat(dirfd, file_path, out_buffer.ptr, out_buffer.len);3436 const rc = system.readlinkat(dirfd, file_path, out_buffer.ptr, out_buffer.len);
3460 switch (errno(rc)) {3437 switch (errno(rc)) {
3461 .SUCCESS => return out_buffer[0..@as(usize, @bitCast(rc))],3438 .SUCCESS => return out_buffer[0..@bitCast(rc)],
3462 .ACCES => return error.AccessDenied,3439 .ACCES => return error.AccessDenied,
3463 .FAULT => unreachable,3440 .FAULT => unreachable,
3464 .INVAL => return error.NotLink,3441 .INVAL => return error.NotLink,
...@@ -3570,7 +3547,7 @@ pub fn isatty(handle: fd_t) bool {...@@ -3570,7 +3547,7 @@ pub fn isatty(handle: fd_t) bool {
3570 if (builtin.os.tag == .linux) {3547 if (builtin.os.tag == .linux) {
3571 while (true) {3548 while (true) {
3572 var wsz: linux.winsize = undefined;3549 var wsz: linux.winsize = undefined;
3573 const fd = @as(usize, @bitCast(@as(isize, handle)));3550 const fd: usize = @bitCast(@as(isize, handle));
3574 const rc = linux.syscall3(.ioctl, fd, linux.T.IOCGWINSZ, @intFromPtr(&wsz));3551 const rc = linux.syscall3(.ioctl, fd, linux.T.IOCGWINSZ, @intFromPtr(&wsz));
3575 switch (linux.getErrno(rc)) {3552 switch (linux.getErrno(rc)) {
3576 .SUCCESS => return true,3553 .SUCCESS => return true,
...@@ -3614,15 +3591,15 @@ pub fn isCygwinPty(handle: fd_t) bool {...@@ -3614,15 +3591,15 @@ pub fn isCygwinPty(handle: fd_t) bool {
3614 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (name_bytes_offset + num_name_bytes);3591 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (name_bytes_offset + num_name_bytes);
36153592
3616 var io_status_block: windows.IO_STATUS_BLOCK = undefined;3593 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
3617 const rc = windows.ntdll.NtQueryInformationFile(handle, &io_status_block, &name_info_bytes, @as(u32, @intCast(name_info_bytes.len)), .FileNameInformation);3594 const rc = windows.ntdll.NtQueryInformationFile(handle, &io_status_block, &name_info_bytes, @intCast(name_info_bytes.len), .FileNameInformation);
3618 switch (rc) {3595 switch (rc) {
3619 .SUCCESS => {},3596 .SUCCESS => {},
3620 .INVALID_PARAMETER => unreachable,3597 .INVALID_PARAMETER => unreachable,
3621 else => return false,3598 else => return false,
3622 }3599 }
36233600
3624 const name_info = @as(*const windows.FILE_NAME_INFO, @ptrCast(&name_info_bytes[0]));3601 const name_info: *const windows.FILE_NAME_INFO = @ptrCast(&name_info_bytes);
3625 const name_bytes = name_info_bytes[name_bytes_offset .. name_bytes_offset + @as(usize, name_info.FileNameLength)];3602 const name_bytes = name_info_bytes[name_bytes_offset .. name_bytes_offset + name_info.FileNameLength];
3626 const name_wide = mem.bytesAsSlice(u16, name_bytes);3603 const name_wide = mem.bytesAsSlice(u16, name_bytes);
3627 // Note: The name we get from NtQueryInformationFile will be prefixed with a '\', e.g. \msys-1888ae32e00d56aa-pty0-to-master3604 // Note: The name we get from NtQueryInformationFile will be prefixed with a '\', e.g. \msys-1888ae32e00d56aa-pty0-to-master
3628 return (mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'm', 's', 'y', 's', '-' }) or3605 return (mem.startsWith(u16, name_wide, &[_]u16{ '\\', 'm', 's', 'y', 's', '-' }) or
...@@ -3668,9 +3645,9 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t...@@ -3668,9 +3645,9 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
3668 else3645 else
3669 0;3646 0;
3670 const rc = try windows.WSASocketW(3647 const rc = try windows.WSASocketW(
3671 @as(i32, @bitCast(domain)),3648 @bitCast(domain),
3672 @as(i32, @bitCast(filtered_sock_type)),3649 @bitCast(filtered_sock_type),
3673 @as(i32, @bitCast(protocol)),3650 @bitCast(protocol),
3674 null,3651 null,
3675 0,3652 0,
3676 flags,3653 flags,
...@@ -3688,7 +3665,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t...@@ -3688,7 +3665,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
3688 return rc;3665 return rc;
3689 }3666 }
36903667
3691 const have_sock_flags = comptime !builtin.target.isDarwin();3668 const have_sock_flags = !builtin.target.isDarwin();
3692 const filtered_sock_type = if (!have_sock_flags)3669 const filtered_sock_type = if (!have_sock_flags)
3693 socket_type & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC)3670 socket_type & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC)
3694 else3671 else
...@@ -3696,7 +3673,8 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t...@@ -3696,7 +3673,8 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!socket_t
3696 const rc = system.socket(domain, filtered_sock_type, protocol);3673 const rc = system.socket(domain, filtered_sock_type, protocol);
3697 switch (errno(rc)) {3674 switch (errno(rc)) {
3698 .SUCCESS => {3675 .SUCCESS => {
3699 const fd = @as(fd_t, @intCast(rc));3676 const fd: fd_t = @intCast(rc);
3677 errdefer close(fd);
3700 if (!have_sock_flags) {3678 if (!have_sock_flags) {
3701 try setSockFlags(fd, socket_type);3679 try setSockFlags(fd, socket_type);
3702 }3680 }
...@@ -3983,10 +3961,10 @@ pub fn accept(...@@ -3983,10 +3961,10 @@ pub fn accept(
3983 /// description of the `CLOEXEC` flag in `open` for reasons why this may be useful.3961 /// description of the `CLOEXEC` flag in `open` for reasons why this may be useful.
3984 flags: u32,3962 flags: u32,
3985) AcceptError!socket_t {3963) AcceptError!socket_t {
3986 const have_accept4 = comptime !(builtin.target.isDarwin() or builtin.os.tag == .windows);3964 const have_accept4 = !(builtin.target.isDarwin() or builtin.os.tag == .windows);
3987 assert(0 == (flags & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC))); // Unsupported flag(s)3965 assert(0 == (flags & ~@as(u32, SOCK.NONBLOCK | SOCK.CLOEXEC))); // Unsupported flag(s)
39883966
3989 const accepted_sock = while (true) {3967 const accepted_sock: socket_t = while (true) {
3990 const rc = if (have_accept4)3968 const rc = if (have_accept4)
3991 system.accept4(sock, addr, addr_size, flags)3969 system.accept4(sock, addr, addr_size, flags)
3992 else if (builtin.os.tag == .windows)3970 else if (builtin.os.tag == .windows)
...@@ -4013,9 +3991,7 @@ pub fn accept(...@@ -4013,9 +3991,7 @@ pub fn accept(
4013 }3991 }
4014 } else {3992 } else {
4015 switch (errno(rc)) {3993 switch (errno(rc)) {
4016 .SUCCESS => {3994 .SUCCESS => break @intCast(rc),
4017 break @as(socket_t, @intCast(rc));
4018 },
4019 .INTR => continue,3995 .INTR => continue,
4020 .AGAIN => return error.WouldBlock,3996 .AGAIN => return error.WouldBlock,
4021 .BADF => unreachable, // always a race condition3997 .BADF => unreachable, // always a race condition
...@@ -4035,6 +4011,10 @@ pub fn accept(...@@ -4035,6 +4011,10 @@ pub fn accept(
4035 }4011 }
4036 };4012 };
40374013
4014 errdefer switch (builtin.os.tag) {
4015 .windows => windows.closesocket(accepted_sock) catch unreachable,
4016 else => close(accepted_sock),
4017 };
4038 if (!have_accept4) {4018 if (!have_accept4) {
4039 try setSockFlags(accepted_sock, flags);4019 try setSockFlags(accepted_sock, flags);
4040 }4020 }
...@@ -4058,7 +4038,7 @@ pub const EpollCreateError = error{...@@ -4058,7 +4038,7 @@ pub const EpollCreateError = error{
4058pub fn epoll_create1(flags: u32) EpollCreateError!i32 {4038pub fn epoll_create1(flags: u32) EpollCreateError!i32 {
4059 const rc = system.epoll_create1(flags);4039 const rc = system.epoll_create1(flags);
4060 switch (errno(rc)) {4040 switch (errno(rc)) {
4061 .SUCCESS => return @as(i32, @intCast(rc)),4041 .SUCCESS => return @intCast(rc),
4062 else => |err| return unexpectedErrno(err),4042 else => |err| return unexpectedErrno(err),
40634043
4064 .INVAL => unreachable,4044 .INVAL => unreachable,
...@@ -4117,9 +4097,9 @@ pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*linux.epoll_event) EpollC...@@ -4117,9 +4097,9 @@ pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*linux.epoll_event) EpollC
4117pub fn epoll_wait(epfd: i32, events: []linux.epoll_event, timeout: i32) usize {4097pub fn epoll_wait(epfd: i32, events: []linux.epoll_event, timeout: i32) usize {
4118 while (true) {4098 while (true) {
4119 // TODO get rid of the @intCast4099 // TODO get rid of the @intCast
4120 const rc = system.epoll_wait(epfd, events.ptr, @as(u32, @intCast(events.len)), timeout);4100 const rc = system.epoll_wait(epfd, events.ptr, @intCast(events.len), timeout);
4121 switch (errno(rc)) {4101 switch (errno(rc)) {
4122 .SUCCESS => return @as(usize, @intCast(rc)),4102 .SUCCESS => return @intCast(rc),
4123 .INTR => continue,4103 .INTR => continue,
4124 .BADF => unreachable,4104 .BADF => unreachable,
4125 .FAULT => unreachable,4105 .FAULT => unreachable,
...@@ -4138,7 +4118,7 @@ pub const EventFdError = error{...@@ -4138,7 +4118,7 @@ pub const EventFdError = error{
4138pub fn eventfd(initval: u32, flags: u32) EventFdError!i32 {4118pub fn eventfd(initval: u32, flags: u32) EventFdError!i32 {
4139 const rc = system.eventfd(initval, flags);4119 const rc = system.eventfd(initval, flags);
4140 switch (errno(rc)) {4120 switch (errno(rc)) {
4141 .SUCCESS => return @as(i32, @intCast(rc)),4121 .SUCCESS => return @intCast(rc),
4142 else => |err| return unexpectedErrno(err),4122 else => |err| return unexpectedErrno(err),
41434123
4144 .INVAL => unreachable, // invalid parameters4124 .INVAL => unreachable, // invalid parameters
...@@ -4272,7 +4252,7 @@ pub const ConnectError = error{...@@ -4272,7 +4252,7 @@ pub const ConnectError = error{
4272/// return error.WouldBlock when EAGAIN or EINPROGRESS is received.4252/// return error.WouldBlock when EAGAIN or EINPROGRESS is received.
4273pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) ConnectError!void {4253pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) ConnectError!void {
4274 if (builtin.os.tag == .windows) {4254 if (builtin.os.tag == .windows) {
4275 const rc = windows.ws2_32.connect(sock, sock_addr, @as(i32, @intCast(len)));4255 const rc = windows.ws2_32.connect(sock, sock_addr, @intCast(len));
4276 if (rc == 0) return;4256 if (rc == 0) return;
4277 switch (windows.ws2_32.WSAGetLastError()) {4257 switch (windows.ws2_32.WSAGetLastError()) {
4278 .WSAEADDRINUSE => return error.AddressInUse,4258 .WSAEADDRINUSE => return error.AddressInUse,
...@@ -4327,7 +4307,7 @@ pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) Conne...@@ -4327,7 +4307,7 @@ pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) Conne
4327pub fn getsockoptError(sockfd: fd_t) ConnectError!void {4307pub fn getsockoptError(sockfd: fd_t) ConnectError!void {
4328 var err_code: i32 = undefined;4308 var err_code: i32 = undefined;
4329 var size: u32 = @sizeOf(u32);4309 var size: u32 = @sizeOf(u32);
4330 const rc = system.getsockopt(sockfd, SOL.SOCKET, SO.ERROR, @as([*]u8, @ptrCast(&err_code)), &size);4310 const rc = system.getsockopt(sockfd, SOL.SOCKET, SO.ERROR, @ptrCast(&err_code), &size);
4331 assert(size == 4);4311 assert(size == 4);
4332 switch (errno(rc)) {4312 switch (errno(rc)) {
4333 .SUCCESS => switch (@as(E, @enumFromInt(err_code))) {4313 .SUCCESS => switch (@as(E, @enumFromInt(err_code))) {
...@@ -4368,15 +4348,13 @@ pub const WaitPidResult = struct {...@@ -4368,15 +4348,13 @@ pub const WaitPidResult = struct {
4368/// Use this version of the `waitpid` wrapper if you spawned your child process using explicit4348/// Use this version of the `waitpid` wrapper if you spawned your child process using explicit
4369/// `fork` and `execve` method.4349/// `fork` and `execve` method.
4370pub fn waitpid(pid: pid_t, flags: u32) WaitPidResult {4350pub fn waitpid(pid: pid_t, flags: u32) WaitPidResult {
4371 const Status = if (builtin.link_libc) c_int else u32;4351 var status: if (builtin.link_libc) c_int else u32 = undefined;
4372 var status: Status = undefined;
4373 const coerced_flags = if (builtin.link_libc) @as(c_int, @intCast(flags)) else flags;
4374 while (true) {4352 while (true) {
4375 const rc = system.waitpid(pid, &status, coerced_flags);4353 const rc = system.waitpid(pid, &status, @intCast(flags));
4376 switch (errno(rc)) {4354 switch (errno(rc)) {
4377 .SUCCESS => return .{4355 .SUCCESS => return .{
4378 .pid = @as(pid_t, @intCast(rc)),4356 .pid = @intCast(rc),
4379 .status = @as(u32, @bitCast(status)),4357 .status = @bitCast(status),
4380 },4358 },
4381 .INTR => continue,4359 .INTR => continue,
4382 .CHILD => unreachable, // The process specified does not exist. It would be a race condition to handle this error.4360 .CHILD => unreachable, // The process specified does not exist. It would be a race condition to handle this error.
...@@ -4387,15 +4365,13 @@ pub fn waitpid(pid: pid_t, flags: u32) WaitPidResult {...@@ -4387,15 +4365,13 @@ pub fn waitpid(pid: pid_t, flags: u32) WaitPidResult {
4387}4365}
43884366
4389pub fn wait4(pid: pid_t, flags: u32, ru: ?*rusage) WaitPidResult {4367pub fn wait4(pid: pid_t, flags: u32, ru: ?*rusage) WaitPidResult {
4390 const Status = if (builtin.link_libc) c_int else u32;4368 var status: if (builtin.link_libc) c_int else u32 = undefined;
4391 var status: Status = undefined;
4392 const coerced_flags = if (builtin.link_libc) @as(c_int, @intCast(flags)) else flags;
4393 while (true) {4369 while (true) {
4394 const rc = system.wait4(pid, &status, coerced_flags, ru);4370 const rc = system.wait4(pid, &status, @intCast(flags), ru);
4395 switch (errno(rc)) {4371 switch (errno(rc)) {
4396 .SUCCESS => return .{4372 .SUCCESS => return .{
4397 .pid = @as(pid_t, @intCast(rc)),4373 .pid = @intCast(rc),
4398 .status = @as(u32, @bitCast(status)),4374 .status = @bitCast(status),
4399 },4375 },
4400 .INTR => continue,4376 .INTR => continue,
4401 .CHILD => unreachable, // The process specified does not exist. It would be a race condition to handle this error.4377 .CHILD => unreachable, // The process specified does not exist. It would be a race condition to handle this error.
...@@ -4423,7 +4399,6 @@ pub fn fstat(fd: fd_t) FStatError!Stat {...@@ -4423,7 +4399,6 @@ pub fn fstat(fd: fd_t) FStatError!Stat {
4423 }4399 }
44244400
4425 const fstat_sym = if (lfs64_abi) system.fstat64 else system.fstat;4401 const fstat_sym = if (lfs64_abi) system.fstat64 else system.fstat;
4426
4427 var stat = mem.zeroes(Stat);4402 var stat = mem.zeroes(Stat);
4428 switch (errno(fstat_sym(fd, &stat))) {4403 switch (errno(fstat_sym(fd, &stat))) {
4429 .SUCCESS => return stat,4404 .SUCCESS => return stat,
...@@ -4507,7 +4482,6 @@ pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!S...@@ -4507,7 +4482,6 @@ pub fn fstatatZ(dirfd: fd_t, pathname: [*:0]const u8, flags: u32) FStatAtError!S
4507 }4482 }
45084483
4509 const fstatat_sym = if (lfs64_abi) system.fstatat64 else system.fstatat;4484 const fstatat_sym = if (lfs64_abi) system.fstatat64 else system.fstatat;
4510
4511 var stat = mem.zeroes(Stat);4485 var stat = mem.zeroes(Stat);
4512 switch (errno(fstatat_sym(dirfd, pathname, &stat, flags))) {4486 switch (errno(fstatat_sym(dirfd, pathname, &stat, flags))) {
4513 .SUCCESS => return stat,4487 .SUCCESS => return stat,
...@@ -4540,7 +4514,7 @@ pub const KQueueError = error{...@@ -4540,7 +4514,7 @@ pub const KQueueError = error{
4540pub fn kqueue() KQueueError!i32 {4514pub fn kqueue() KQueueError!i32 {
4541 const rc = system.kqueue();4515 const rc = system.kqueue();
4542 switch (errno(rc)) {4516 switch (errno(rc)) {
4543 .SUCCESS => return @as(i32, @intCast(rc)),4517 .SUCCESS => return @intCast(rc),
4544 .MFILE => return error.ProcessFdQuotaExceeded,4518 .MFILE => return error.ProcessFdQuotaExceeded,
4545 .NFILE => return error.SystemFdQuotaExceeded,4519 .NFILE => return error.SystemFdQuotaExceeded,
4546 else => |err| return unexpectedErrno(err),4520 else => |err| return unexpectedErrno(err),
...@@ -4581,7 +4555,7 @@ pub fn kevent(...@@ -4581,7 +4555,7 @@ pub fn kevent(
4581 timeout,4555 timeout,
4582 );4556 );
4583 switch (errno(rc)) {4557 switch (errno(rc)) {
4584 .SUCCESS => return @as(usize, @intCast(rc)),4558 .SUCCESS => return @intCast(rc),
4585 .ACCES => return error.AccessDenied,4559 .ACCES => return error.AccessDenied,
4586 .FAULT => unreachable,4560 .FAULT => unreachable,
4587 .BADF => unreachable, // Always a race condition.4561 .BADF => unreachable, // Always a race condition.
...@@ -4605,7 +4579,7 @@ pub const INotifyInitError = error{...@@ -4605,7 +4579,7 @@ pub const INotifyInitError = error{
4605pub fn inotify_init1(flags: u32) INotifyInitError!i32 {4579pub fn inotify_init1(flags: u32) INotifyInitError!i32 {
4606 const rc = system.inotify_init1(flags);4580 const rc = system.inotify_init1(flags);
4607 switch (errno(rc)) {4581 switch (errno(rc)) {
4608 .SUCCESS => return @as(i32, @intCast(rc)),4582 .SUCCESS => return @intCast(rc),
4609 .INVAL => unreachable,4583 .INVAL => unreachable,
4610 .MFILE => return error.ProcessFdQuotaExceeded,4584 .MFILE => return error.ProcessFdQuotaExceeded,
4611 .NFILE => return error.SystemFdQuotaExceeded,4585 .NFILE => return error.SystemFdQuotaExceeded,
...@@ -4634,7 +4608,7 @@ pub fn inotify_add_watch(inotify_fd: i32, pathname: []const u8, mask: u32) INoti...@@ -4634,7 +4608,7 @@ pub fn inotify_add_watch(inotify_fd: i32, pathname: []const u8, mask: u32) INoti
4634pub fn inotify_add_watchZ(inotify_fd: i32, pathname: [*:0]const u8, mask: u32) INotifyAddWatchError!i32 {4608pub fn inotify_add_watchZ(inotify_fd: i32, pathname: [*:0]const u8, mask: u32) INotifyAddWatchError!i32 {
4635 const rc = system.inotify_add_watch(inotify_fd, pathname, mask);4609 const rc = system.inotify_add_watch(inotify_fd, pathname, mask);
4636 switch (errno(rc)) {4610 switch (errno(rc)) {
4637 .SUCCESS => return @as(i32, @intCast(rc)),4611 .SUCCESS => return @intCast(rc),
4638 .ACCES => return error.AccessDenied,4612 .ACCES => return error.AccessDenied,
4639 .BADF => unreachable,4613 .BADF => unreachable,
4640 .FAULT => unreachable,4614 .FAULT => unreachable,
...@@ -4670,7 +4644,7 @@ pub const FanotifyInitError = error{...@@ -4670,7 +4644,7 @@ pub const FanotifyInitError = error{
4670pub fn fanotify_init(flags: u32, event_f_flags: u32) FanotifyInitError!i32 {4644pub fn fanotify_init(flags: u32, event_f_flags: u32) FanotifyInitError!i32 {
4671 const rc = system.fanotify_init(flags, event_f_flags);4645 const rc = system.fanotify_init(flags, event_f_flags);
4672 switch (errno(rc)) {4646 switch (errno(rc)) {
4673 .SUCCESS => return @as(i32, @intCast(rc)),4647 .SUCCESS => return @intCast(rc),
4674 .INVAL => unreachable,4648 .INVAL => unreachable,
4675 .MFILE => return error.ProcessFdQuotaExceeded,4649 .MFILE => return error.ProcessFdQuotaExceeded,
4676 .NFILE => return error.SystemFdQuotaExceeded,4650 .NFILE => return error.SystemFdQuotaExceeded,
...@@ -4775,7 +4749,7 @@ pub const ForkError = error{SystemResources} || UnexpectedError;...@@ -4775,7 +4749,7 @@ pub const ForkError = error{SystemResources} || UnexpectedError;
4775pub fn fork() ForkError!pid_t {4749pub fn fork() ForkError!pid_t {
4776 const rc = system.fork();4750 const rc = system.fork();
4777 switch (errno(rc)) {4751 switch (errno(rc)) {
4778 .SUCCESS => return @as(pid_t, @intCast(rc)),4752 .SUCCESS => return @intCast(rc),
4779 .AGAIN => return error.SystemResources,4753 .AGAIN => return error.SystemResources,
4780 .NOMEM => return error.SystemResources,4754 .NOMEM => return error.SystemResources,
4781 else => |err| return unexpectedErrno(err),4755 else => |err| return unexpectedErrno(err),
...@@ -4815,12 +4789,10 @@ pub fn mmap(...@@ -4815,12 +4789,10 @@ pub fn mmap(
4815 offset: u64,4789 offset: u64,
4816) MMapError![]align(mem.page_size) u8 {4790) MMapError![]align(mem.page_size) u8 {
4817 const mmap_sym = if (lfs64_abi) system.mmap64 else system.mmap;4791 const mmap_sym = if (lfs64_abi) system.mmap64 else system.mmap;
48184792 const rc = mmap_sym(ptr, length, prot, @bitCast(flags), fd, @bitCast(offset));
4819 const ioffset: i64 = @bitCast(offset); // the OS treats this as unsigned4793 const err: E = if (builtin.link_libc) blk: {
4820 const rc = mmap_sym(ptr, length, prot, @bitCast(flags), fd, ioffset);
4821 const err = if (builtin.link_libc) blk: {
4822 if (rc != std.c.MAP_FAILED) return @as([*]align(mem.page_size) u8, @ptrCast(@alignCast(rc)))[0..length];4794 if (rc != std.c.MAP_FAILED) return @as([*]align(mem.page_size) u8, @ptrCast(@alignCast(rc)))[0..length];
4823 break :blk @as(E, @enumFromInt(system._errno().*));4795 break :blk @enumFromInt(system._errno().*);
4824 } else blk: {4796 } else blk: {
4825 const err = errno(rc);4797 const err = errno(rc);
4826 if (err == .SUCCESS) return @as([*]align(mem.page_size) u8, @ptrFromInt(rc))[0..length];4798 if (err == .SUCCESS) return @as([*]align(mem.page_size) u8, @ptrFromInt(rc))[0..length];
...@@ -5245,7 +5217,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {...@@ -5245,7 +5217,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
5245 }5217 }
5246 if (builtin.os.tag == .wasi and !builtin.link_libc) {5218 if (builtin.os.tag == .wasi and !builtin.link_libc) {
5247 var new_offset: wasi.filesize_t = undefined;5219 var new_offset: wasi.filesize_t = undefined;
5248 switch (wasi.fd_seek(fd, @as(wasi.filedelta_t, @bitCast(offset)), .SET, &new_offset)) {5220 switch (wasi.fd_seek(fd, @bitCast(offset), .SET, &new_offset)) {
5249 .SUCCESS => return,5221 .SUCCESS => return,
5250 .BADF => unreachable, // always a race condition5222 .BADF => unreachable, // always a race condition
5251 .INVAL => return error.Unseekable,5223 .INVAL => return error.Unseekable,
...@@ -5258,9 +5230,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {...@@ -5258,9 +5230,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
5258 }5230 }
52595231
5260 const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;5232 const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;
52615233 switch (errno(lseek_sym(fd, @bitCast(offset), SEEK.SET))) {
5262 const ioffset = @as(i64, @bitCast(offset)); // the OS treats this as unsigned
5263 switch (errno(lseek_sym(fd, ioffset, SEEK.SET))) {
5264 .SUCCESS => return,5234 .SUCCESS => return,
5265 .BADF => unreachable, // always a race condition5235 .BADF => unreachable, // always a race condition
5266 .INVAL => return error.Unseekable,5236 .INVAL => return error.Unseekable,
...@@ -5275,7 +5245,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {...@@ -5275,7 +5245,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
5275pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {5245pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
5276 if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {5246 if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
5277 var result: u64 = undefined;5247 var result: u64 = undefined;
5278 switch (errno(system.llseek(fd, @as(u64, @bitCast(offset)), &result, SEEK.CUR))) {5248 switch (errno(system.llseek(fd, @bitCast(offset), &result, SEEK.CUR))) {
5279 .SUCCESS => return,5249 .SUCCESS => return,
5280 .BADF => unreachable, // always a race condition5250 .BADF => unreachable, // always a race condition
5281 .INVAL => return error.Unseekable,5251 .INVAL => return error.Unseekable,
...@@ -5302,9 +5272,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {...@@ -5302,9 +5272,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
5302 }5272 }
5303 }5273 }
5304 const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;5274 const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;
53055275 switch (errno(lseek_sym(fd, @bitCast(offset), SEEK.CUR))) {
5306 const ioffset = @as(i64, @bitCast(offset)); // the OS treats this as unsigned
5307 switch (errno(lseek_sym(fd, ioffset, SEEK.CUR))) {
5308 .SUCCESS => return,5276 .SUCCESS => return,
5309 .BADF => unreachable, // always a race condition5277 .BADF => unreachable, // always a race condition
5310 .INVAL => return error.Unseekable,5278 .INVAL => return error.Unseekable,
...@@ -5319,7 +5287,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {...@@ -5319,7 +5287,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
5319pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {5287pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
5320 if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {5288 if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
5321 var result: u64 = undefined;5289 var result: u64 = undefined;
5322 switch (errno(system.llseek(fd, @as(u64, @bitCast(offset)), &result, SEEK.END))) {5290 switch (errno(system.llseek(fd, @bitCast(offset), &result, SEEK.END))) {
5323 .SUCCESS => return,5291 .SUCCESS => return,
5324 .BADF => unreachable, // always a race condition5292 .BADF => unreachable, // always a race condition
5325 .INVAL => return error.Unseekable,5293 .INVAL => return error.Unseekable,
...@@ -5346,9 +5314,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {...@@ -5346,9 +5314,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
5346 }5314 }
5347 }5315 }
5348 const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;5316 const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;
53495317 switch (errno(lseek_sym(fd, @bitCast(offset), SEEK.END))) {
5350 const ioffset = @as(i64, @bitCast(offset)); // the OS treats this as unsigned
5351 switch (errno(lseek_sym(fd, ioffset, SEEK.END))) {
5352 .SUCCESS => return,5318 .SUCCESS => return,
5353 .BADF => unreachable, // always a race condition5319 .BADF => unreachable, // always a race condition
5354 .INVAL => return error.Unseekable,5320 .INVAL => return error.Unseekable,
...@@ -5390,10 +5356,9 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {...@@ -5390,10 +5356,9 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
5390 }5356 }
5391 }5357 }
5392 const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;5358 const lseek_sym = if (lfs64_abi) system.lseek64 else system.lseek;
5393
5394 const rc = lseek_sym(fd, 0, SEEK.CUR);5359 const rc = lseek_sym(fd, 0, SEEK.CUR);
5395 switch (errno(rc)) {5360 switch (errno(rc)) {
5396 .SUCCESS => return @as(u64, @bitCast(rc)),5361 .SUCCESS => return @bitCast(rc),
5397 .BADF => unreachable, // always a race condition5362 .BADF => unreachable, // always a race condition
5398 .INVAL => return error.Unseekable,5363 .INVAL => return error.Unseekable,
5399 .OVERFLOW => return error.Unseekable,5364 .OVERFLOW => return error.Unseekable,
...@@ -5416,7 +5381,7 @@ pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {...@@ -5416,7 +5381,7 @@ pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {
5416 while (true) {5381 while (true) {
5417 const rc = system.fcntl(fd, cmd, arg);5382 const rc = system.fcntl(fd, cmd, arg);
5418 switch (errno(rc)) {5383 switch (errno(rc)) {
5419 .SUCCESS => return @as(usize, @intCast(rc)),5384 .SUCCESS => return @intCast(rc),
5420 .INTR => continue,5385 .INTR => continue,
5421 .AGAIN, .ACCES => return error.Locked,5386 .AGAIN, .ACCES => return error.Locked,
5422 .BADF => unreachable,5387 .BADF => unreachable,
...@@ -5709,7 +5674,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {...@@ -5709,7 +5674,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
5709 // errno values to expect when command is F.GETPATH...5674 // errno values to expect when command is F.GETPATH...
5710 else => |err| return unexpectedErrno(err),5675 else => |err| return unexpectedErrno(err),
5711 }5676 }
5712 const len = mem.indexOfScalar(u8, out_buffer[0..], @as(u8, 0)) orelse MAX_PATH_BYTES;5677 const len = mem.indexOfScalar(u8, out_buffer[0..], 0) orelse MAX_PATH_BYTES;
5713 return out_buffer[0..len];5678 return out_buffer[0..len];
5714 },5679 },
5715 .linux => {5680 .linux => {
...@@ -5741,7 +5706,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {...@@ -5741,7 +5706,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
5741 return target;5706 return target;
5742 },5707 },
5743 .freebsd => {5708 .freebsd => {
5744 if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0, .patch = 0 }) == .gt) {5709 if (comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) {
5745 var kfile: system.kinfo_file = undefined;5710 var kfile: system.kinfo_file = undefined;
5746 kfile.structsize = system.KINFO_FILE_SIZE;5711 kfile.structsize = system.KINFO_FILE_SIZE;
5747 switch (errno(system.fcntl(fd, system.F.KINFO, @intFromPtr(&kfile)))) {5712 switch (errno(system.fcntl(fd, system.F.KINFO, @intFromPtr(&kfile)))) {
...@@ -5780,7 +5745,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {...@@ -5780,7 +5745,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
5780 };5745 };
5781 var i: usize = 0;5746 var i: usize = 0;
5782 while (i < len) {5747 while (i < len) {
5783 const kf: *align(1) system.kinfo_file = @as(*align(1) system.kinfo_file, @ptrCast(&buf[i]));5748 const kf: *align(1) system.kinfo_file = @ptrCast(&buf[i]);
5784 if (kf.fd == fd) {5749 if (kf.fd == fd) {
5785 len = mem.indexOfScalar(u8, &kf.path, 0) orelse MAX_PATH_BYTES;5750 len = mem.indexOfScalar(u8, &kf.path, 0) orelse MAX_PATH_BYTES;
5786 if (len == 0) return error.NameTooLong;5751 if (len == 0) return error.NameTooLong;
...@@ -5788,7 +5753,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {...@@ -5788,7 +5753,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
5788 @memcpy(result, kf.path[0..len]);5753 @memcpy(result, kf.path[0..len]);
5789 return result;5754 return result;
5790 }5755 }
5791 i += @as(usize, @intCast(kf.structsize));5756 i += @intCast(kf.structsize);
5792 }5757 }
5793 return error.FileNotFound;5758 return error.FileNotFound;
5794 }5759 }
...@@ -5801,7 +5766,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {...@@ -5801,7 +5766,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
5801 .RANGE => return error.NameTooLong,5766 .RANGE => return error.NameTooLong,
5802 else => |err| return unexpectedErrno(err),5767 else => |err| return unexpectedErrno(err),
5803 }5768 }
5804 const len = mem.indexOfScalar(u8, out_buffer[0..], @as(u8, 0)) orelse MAX_PATH_BYTES;5769 const len = mem.indexOfScalar(u8, out_buffer[0..], 0) orelse MAX_PATH_BYTES;
5805 return out_buffer[0..len];5770 return out_buffer[0..len];
5806 },5771 },
5807 .netbsd => {5772 .netbsd => {
...@@ -5815,7 +5780,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {...@@ -5815,7 +5780,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
5815 .RANGE => return error.NameTooLong,5780 .RANGE => return error.NameTooLong,
5816 else => |err| return unexpectedErrno(err),5781 else => |err| return unexpectedErrno(err),
5817 }5782 }
5818 const len = mem.indexOfScalar(u8, out_buffer[0..], @as(u8, 0)) orelse MAX_PATH_BYTES;5783 const len = mem.indexOfScalar(u8, out_buffer[0..], 0) orelse MAX_PATH_BYTES;
5819 return out_buffer[0..len];5784 return out_buffer[0..len];
5820 },5785 },
5821 else => unreachable, // made unreachable by isGetFdPathSupportedOnTarget above5786 else => unreachable, // made unreachable by isGetFdPathSupportedOnTarget above
...@@ -5866,14 +5831,14 @@ pub fn dl_iterate_phdr(...@@ -5866,14 +5831,14 @@ pub fn dl_iterate_phdr(
5866 callback(info, size, context_ptr.*) catch |err| return @intFromError(err);5831 callback(info, size, context_ptr.*) catch |err| return @intFromError(err);
5867 return 0;5832 return 0;
5868 }5833 }
5869 }.callbackC, @as(?*anyopaque, @ptrFromInt(@intFromPtr(&context))))) {5834 }.callbackC, @ptrCast(@constCast(&context)))) {
5870 0 => return,5835 0 => return,
5871 else => |err| return @as(Error, @errorCast(@errorFromInt(@as(std.meta.Int(.unsigned, @bitSizeOf(anyerror)), @intCast(err))))),5836 else => |err| return @as(Error, @errorCast(@errorFromInt(@as(std.meta.Int(.unsigned, @bitSizeOf(anyerror)), @intCast(err))))),
5872 }5837 }
5873 }5838 }
58745839
5875 const elf_base = std.process.getBaseAddress();5840 const elf_base = std.process.getBaseAddress();
5876 const ehdr = @as(*elf.Ehdr, @ptrFromInt(elf_base));5841 const ehdr: *elf.Ehdr = @ptrFromInt(elf_base);
5877 // Make sure the base address points to an ELF image.5842 // Make sure the base address points to an ELF image.
5878 assert(mem.eql(u8, ehdr.e_ident[0..4], elf.MAGIC));5843 assert(mem.eql(u8, ehdr.e_ident[0..4], elf.MAGIC));
5879 const n_phdr = ehdr.e_phnum;5844 const n_phdr = ehdr.e_phnum;
...@@ -5911,12 +5876,12 @@ pub fn dl_iterate_phdr(...@@ -5911,12 +5876,12 @@ pub fn dl_iterate_phdr(
5911 var dlpi_phnum: u16 = undefined;5876 var dlpi_phnum: u16 = undefined;
59125877
5913 if (entry.l_addr != 0) {5878 if (entry.l_addr != 0) {
5914 const elf_header = @as(*elf.Ehdr, @ptrFromInt(entry.l_addr));5879 const elf_header: *elf.Ehdr = @ptrFromInt(entry.l_addr);
5915 dlpi_phdr = @as([*]elf.Phdr, @ptrFromInt(entry.l_addr + elf_header.e_phoff));5880 dlpi_phdr = @ptrFromInt(entry.l_addr + elf_header.e_phoff);
5916 dlpi_phnum = elf_header.e_phnum;5881 dlpi_phnum = elf_header.e_phnum;
5917 } else {5882 } else {
5918 // This is the running ELF image5883 // This is the running ELF image
5919 dlpi_phdr = @as([*]elf.Phdr, @ptrFromInt(elf_base + ehdr.e_phoff));5884 dlpi_phdr = @ptrFromInt(elf_base + ehdr.e_phoff);
5920 dlpi_phnum = ehdr.e_phnum;5885 dlpi_phnum = ehdr.e_phnum;
5921 }5886 }
59225887
...@@ -5938,11 +5903,11 @@ pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;...@@ -5938,11 +5903,11 @@ pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;
5938pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {5903pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
5939 if (builtin.os.tag == .wasi and !builtin.link_libc) {5904 if (builtin.os.tag == .wasi and !builtin.link_libc) {
5940 var ts: timestamp_t = undefined;5905 var ts: timestamp_t = undefined;
5941 switch (system.clock_time_get(@as(u32, @bitCast(clk_id)), 1, &ts)) {5906 switch (system.clock_time_get(@bitCast(clk_id), 1, &ts)) {
5942 .SUCCESS => {5907 .SUCCESS => {
5943 tp.* = .{5908 tp.* = .{
5944 .tv_sec = @as(i64, @intCast(ts / std.time.ns_per_s)),5909 .tv_sec = @intCast(ts / std.time.ns_per_s),
5945 .tv_nsec = @as(isize, @intCast(ts % std.time.ns_per_s)),5910 .tv_nsec = @intCast(ts % std.time.ns_per_s),
5946 };5911 };
5947 },5912 },
5948 .INVAL => return error.UnsupportedClock,5913 .INVAL => return error.UnsupportedClock,
...@@ -5979,10 +5944,10 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {...@@ -5979,10 +5944,10 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
5979pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {5944pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {
5980 if (builtin.os.tag == .wasi and !builtin.link_libc) {5945 if (builtin.os.tag == .wasi and !builtin.link_libc) {
5981 var ts: timestamp_t = undefined;5946 var ts: timestamp_t = undefined;
5982 switch (system.clock_res_get(@as(u32, @bitCast(clk_id)), &ts)) {5947 switch (system.clock_res_get(@bitCast(clk_id), &ts)) {
5983 .SUCCESS => res.* = .{5948 .SUCCESS => res.* = .{
5984 .tv_sec = @as(i64, @intCast(ts / std.time.ns_per_s)),5949 .tv_sec = @intCast(ts / std.time.ns_per_s),
5985 .tv_nsec = @as(isize, @intCast(ts % std.time.ns_per_s)),5950 .tv_nsec = @intCast(ts % std.time.ns_per_s),
5986 },5951 },
5987 .INVAL => return error.UnsupportedClock,5952 .INVAL => return error.UnsupportedClock,
5988 else => |err| return unexpectedErrno(err),5953 else => |err| return unexpectedErrno(err),
...@@ -6207,7 +6172,7 @@ pub fn res_mkquery(...@@ -6207,7 +6172,7 @@ pub fn res_mkquery(
6207 // TODO determine the circumstances for this and whether or6172 // TODO determine the circumstances for this and whether or
6208 // not this should be an error.6173 // not this should be an error.
6209 if (j - i - 1 > 62) unreachable;6174 if (j - i - 1 > 62) unreachable;
6210 q[i - 1] = @as(u8, @intCast(j - i));6175 q[i - 1] = @intCast(j - i);
6211 }6176 }
6212 q[i + 1] = ty;6177 q[i + 1] = ty;
6213 q[i + 3] = class;6178 q[i + 3] = class;
...@@ -6216,10 +6181,10 @@ pub fn res_mkquery(...@@ -6216,10 +6181,10 @@ pub fn res_mkquery(
6216 var ts: timespec = undefined;6181 var ts: timespec = undefined;
6217 clock_gettime(CLOCK.REALTIME, &ts) catch {};6182 clock_gettime(CLOCK.REALTIME, &ts) catch {};
6218 const UInt = std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(ts.tv_nsec)));6183 const UInt = std.meta.Int(.unsigned, @bitSizeOf(@TypeOf(ts.tv_nsec)));
6219 const unsec = @as(UInt, @bitCast(ts.tv_nsec));6184 const unsec: UInt = @bitCast(ts.tv_nsec);
6220 const id = @as(u32, @truncate(unsec + unsec / 65536));6185 const id: u32 = @truncate(unsec + unsec / 65536);
6221 q[0] = @as(u8, @truncate(id / 256));6186 q[0] = @truncate(id / 256);
6222 q[1] = @as(u8, @truncate(id));6187 q[1] = @truncate(id);
62236188
6224 @memcpy(buf[0..n], q[0..n]);6189 @memcpy(buf[0..n], q[0..n]);
6225 return n;6190 return n;
...@@ -6325,11 +6290,11 @@ pub fn sendmsg(...@@ -6325,11 +6290,11 @@ pub fn sendmsg(
6325 else => |err| return windows.unexpectedWSAError(err),6290 else => |err| return windows.unexpectedWSAError(err),
6326 }6291 }
6327 } else {6292 } else {
6328 return @as(usize, @intCast(rc));6293 return @intCast(rc);
6329 }6294 }
6330 } else {6295 } else {
6331 switch (errno(rc)) {6296 switch (errno(rc)) {
6332 .SUCCESS => return @as(usize, @intCast(rc)),6297 .SUCCESS => return @intCast(rc),
63336298
6334 .ACCES => return error.AccessDenied,6299 .ACCES => return error.AccessDenied,
6335 .AGAIN => return error.WouldBlock,6300 .AGAIN => return error.WouldBlock,
...@@ -6425,13 +6390,13 @@ pub fn sendto(...@@ -6425,13 +6390,13 @@ pub fn sendto(
6425 .WSANOTINITIALISED => unreachable, // A successful WSAStartup call must occur before using this function.6390 .WSANOTINITIALISED => unreachable, // A successful WSAStartup call must occur before using this function.
6426 else => |err| return windows.unexpectedWSAError(err),6391 else => |err| return windows.unexpectedWSAError(err),
6427 },6392 },
6428 else => |rc| return @as(usize, @intCast(rc)),6393 else => |rc| return @intCast(rc),
6429 }6394 }
6430 }6395 }
6431 while (true) {6396 while (true) {
6432 const rc = system.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen);6397 const rc = system.sendto(sockfd, buf.ptr, buf.len, flags, dest_addr, addrlen);
6433 switch (errno(rc)) {6398 switch (errno(rc)) {
6434 .SUCCESS => return @as(usize, @intCast(rc)),6399 .SUCCESS => return @intCast(rc),
64356400
6436 .ACCES => return error.AccessDenied,6401 .ACCES => return error.AccessDenied,
6437 .AGAIN => return error.WouldBlock,6402 .AGAIN => return error.WouldBlock,
...@@ -6583,18 +6548,15 @@ pub fn sendfile(...@@ -6583,18 +6548,15 @@ pub fn sendfile(
6583 }6548 }
65846549
6585 // Here we match BSD behavior, making a zero count value send as many bytes as possible.6550 // Here we match BSD behavior, making a zero count value send as many bytes as possible.
6586 const adjusted_count_tmp = if (in_len == 0) max_count else @min(in_len, @as(size_t, max_count));6551 const adjusted_count = if (in_len == 0) max_count else @min(in_len, max_count);
6587 // TODO we should not need this cast; improve return type of @min
6588 const adjusted_count = @as(usize, @intCast(adjusted_count_tmp));
65896552
6590 const sendfile_sym = if (lfs64_abi) system.sendfile64 else system.sendfile;6553 const sendfile_sym = if (lfs64_abi) system.sendfile64 else system.sendfile;
6591
6592 while (true) {6554 while (true) {
6593 var offset: off_t = @as(off_t, @bitCast(in_offset));6555 var offset: off_t = @bitCast(in_offset);
6594 const rc = sendfile_sym(out_fd, in_fd, &offset, adjusted_count);6556 const rc = sendfile_sym(out_fd, in_fd, &offset, adjusted_count);
6595 switch (errno(rc)) {6557 switch (errno(rc)) {
6596 .SUCCESS => {6558 .SUCCESS => {
6597 const amt = @as(usize, @bitCast(rc));6559 const amt: usize = @bitCast(rc);
6598 total_written += amt;6560 total_written += amt;
6599 if (in_len == 0 and amt == 0) {6561 if (in_len == 0 and amt == 0) {
6600 // We have detected EOF from `in_fd`.6562 // We have detected EOF from `in_fd`.
...@@ -6660,13 +6622,10 @@ pub fn sendfile(...@@ -6660,13 +6622,10 @@ pub fn sendfile(
6660 hdtr = &hdtr_data;6622 hdtr = &hdtr_data;
6661 }6623 }
66626624
6663 const adjusted_count = @min(in_len, max_count);
6664
6665 while (true) {6625 while (true) {
6666 var sbytes: off_t = undefined;6626 var sbytes: off_t = undefined;
6667 const offset = @as(off_t, @bitCast(in_offset));6627 const err = errno(system.sendfile(in_fd, out_fd, @bitCast(in_offset), @min(in_len, max_count), hdtr, &sbytes, flags));
6668 const err = errno(system.sendfile(in_fd, out_fd, offset, adjusted_count, hdtr, &sbytes, flags));6628 const amt: usize = @bitCast(sbytes);
6669 const amt = @as(usize, @bitCast(sbytes));
6670 switch (err) {6629 switch (err) {
6671 .SUCCESS => return amt,6630 .SUCCESS => return amt,
66726631
...@@ -6733,15 +6692,10 @@ pub fn sendfile(...@@ -6733,15 +6692,10 @@ pub fn sendfile(
6733 hdtr = &hdtr_data;6692 hdtr = &hdtr_data;
6734 }6693 }
67356694
6736 const adjusted_count_temporary = @min(in_len, @as(u63, max_count));
6737 // TODO we should not need this int cast; improve the return type of `@min`
6738 const adjusted_count = @as(u63, @intCast(adjusted_count_temporary));
6739
6740 while (true) {6695 while (true) {
6741 var sbytes: off_t = adjusted_count;6696 var sbytes: off_t = @min(in_len, max_count);
6742 const signed_offset = @as(i64, @bitCast(in_offset));6697 const err = errno(system.sendfile(in_fd, out_fd, @bitCast(in_offset), &sbytes, hdtr, flags));
6743 const err = errno(system.sendfile(in_fd, out_fd, signed_offset, &sbytes, hdtr, flags));6698 const amt: usize = @bitCast(sbytes);
6744 const amt = @as(usize, @bitCast(sbytes));
6745 switch (err) {6699 switch (err) {
6746 .SUCCESS => return amt,6700 .SUCCESS => return amt,
67476701
...@@ -6786,9 +6740,7 @@ pub fn sendfile(...@@ -6786,9 +6740,7 @@ pub fn sendfile(
6786 rw: {6740 rw: {
6787 var buf: [8 * 4096]u8 = undefined;6741 var buf: [8 * 4096]u8 = undefined;
6788 // Here we match BSD behavior, making a zero count value send as many bytes as possible.6742 // Here we match BSD behavior, making a zero count value send as many bytes as possible.
6789 const adjusted_count_tmp = if (in_len == 0) buf.len else @min(buf.len, in_len);6743 const adjusted_count = if (in_len == 0) buf.len else @min(buf.len, in_len);
6790 // TODO we should not need this cast; improve return type of @min
6791 const adjusted_count = @as(usize, @intCast(adjusted_count_tmp));
6792 const amt_read = try pread(in_fd, buf[0..adjusted_count], in_offset);6744 const amt_read = try pread(in_fd, buf[0..adjusted_count], in_offset);
6793 if (amt_read == 0) {6745 if (amt_read == 0) {
6794 if (in_len == 0) {6746 if (in_len == 0) {
...@@ -6859,14 +6811,14 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len...@@ -6859,14 +6811,14 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len
6859 std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 })) and6811 std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 })) and
6860 has_copy_file_range_syscall.load(.Monotonic)))6812 has_copy_file_range_syscall.load(.Monotonic)))
6861 {6813 {
6862 var off_in_copy = @as(i64, @bitCast(off_in));6814 var off_in_copy: i64 = @bitCast(off_in);
6863 var off_out_copy = @as(i64, @bitCast(off_out));6815 var off_out_copy: i64 = @bitCast(off_out);
68646816
6865 while (true) {6817 while (true) {
6866 const rc = system.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags);6818 const rc = system.copy_file_range(fd_in, &off_in_copy, fd_out, &off_out_copy, len, flags);
6867 if (builtin.os.tag == .freebsd) {6819 if (builtin.os.tag == .freebsd) {
6868 switch (system.getErrno(rc)) {6820 switch (system.getErrno(rc)) {
6869 .SUCCESS => return @as(usize, @intCast(rc)),6821 .SUCCESS => return @intCast(rc),
6870 .BADF => return error.FilesOpenedWithWrongFlags,6822 .BADF => return error.FilesOpenedWithWrongFlags,
6871 .FBIG => return error.FileTooBig,6823 .FBIG => return error.FileTooBig,
6872 .IO => return error.InputOutput,6824 .IO => return error.InputOutput,
...@@ -6879,7 +6831,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len...@@ -6879,7 +6831,7 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len
6879 }6831 }
6880 } else { // assume linux6832 } else { // assume linux
6881 switch (system.getErrno(rc)) {6833 switch (system.getErrno(rc)) {
6882 .SUCCESS => return @as(usize, @intCast(rc)),6834 .SUCCESS => return @intCast(rc),
6883 .BADF => return error.FilesOpenedWithWrongFlags,6835 .BADF => return error.FilesOpenedWithWrongFlags,
6884 .FBIG => return error.FileTooBig,6836 .FBIG => return error.FileTooBig,
6885 .IO => return error.InputOutput,6837 .IO => return error.InputOutput,
...@@ -6902,11 +6854,8 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len...@@ -6902,11 +6854,8 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len
6902 }6854 }
69036855
6904 var buf: [8 * 4096]u8 = undefined;6856 var buf: [8 * 4096]u8 = undefined;
6905 const adjusted_count = @min(buf.len, len);6857 const amt_read = try pread(fd_in, buf[0..@min(buf.len, len)], off_in);
6906 const amt_read = try pread(fd_in, buf[0..adjusted_count], off_in);6858 if (amt_read == 0) return 0;
6907 // TODO without @as the line below fails to compile for wasm32-wasi:
6908 // error: integer value 0 cannot be coerced to type 'os.PWriteError!usize'
6909 if (amt_read == 0) return @as(usize, 0);
6910 return pwrite(fd_out, buf[0..amt_read], off_out);6859 return pwrite(fd_out, buf[0..amt_read], off_out);
6911}6860}
69126861
...@@ -6932,11 +6881,11 @@ pub fn poll(fds: []pollfd, timeout: i32) PollError!usize {...@@ -6932,11 +6881,11 @@ pub fn poll(fds: []pollfd, timeout: i32) PollError!usize {
6932 else => |err| return windows.unexpectedWSAError(err),6881 else => |err| return windows.unexpectedWSAError(err),
6933 }6882 }
6934 } else {6883 } else {
6935 return @as(usize, @intCast(rc));6884 return @intCast(rc);
6936 }6885 }
6937 } else {6886 } else {
6938 switch (errno(rc)) {6887 switch (errno(rc)) {
6939 .SUCCESS => return @as(usize, @intCast(rc)),6888 .SUCCESS => return @intCast(rc),
6940 .FAULT => unreachable,6889 .FAULT => unreachable,
6941 .INTR => continue,6890 .INTR => continue,
6942 .INVAL => unreachable,6891 .INVAL => unreachable,
...@@ -6966,7 +6915,7 @@ pub fn ppoll(fds: []pollfd, timeout: ?*const timespec, mask: ?*const sigset_t) P...@@ -6966,7 +6915,7 @@ pub fn ppoll(fds: []pollfd, timeout: ?*const timespec, mask: ?*const sigset_t) P
6966 const fds_count = math.cast(nfds_t, fds.len) orelse return error.SystemResources;6915 const fds_count = math.cast(nfds_t, fds.len) orelse return error.SystemResources;
6967 const rc = system.ppoll(fds.ptr, fds_count, ts_ptr, mask);6916 const rc = system.ppoll(fds.ptr, fds_count, ts_ptr, mask);
6968 switch (errno(rc)) {6917 switch (errno(rc)) {
6969 .SUCCESS => return @as(usize, @intCast(rc)),6918 .SUCCESS => return @intCast(rc),
6970 .FAULT => unreachable,6919 .FAULT => unreachable,
6971 .INTR => return error.SignalInterrupt,6920 .INTR => return error.SignalInterrupt,
6972 .INVAL => unreachable,6921 .INVAL => unreachable,
...@@ -7033,11 +6982,11 @@ pub fn recvfrom(...@@ -7033,11 +6982,11 @@ pub fn recvfrom(
7033 else => |err| return windows.unexpectedWSAError(err),6982 else => |err| return windows.unexpectedWSAError(err),
7034 }6983 }
7035 } else {6984 } else {
7036 return @as(usize, @intCast(rc));6985 return @intCast(rc);
7037 }6986 }
7038 } else {6987 } else {
7039 switch (errno(rc)) {6988 switch (errno(rc)) {
7040 .SUCCESS => return @as(usize, @intCast(rc)),6989 .SUCCESS => return @intCast(rc),
7041 .BADF => unreachable, // always a race condition6990 .BADF => unreachable, // always a race condition
7042 .FAULT => unreachable,6991 .FAULT => unreachable,
7043 .INVAL => unreachable,6992 .INVAL => unreachable,
...@@ -7076,7 +7025,7 @@ pub fn dn_expand(...@@ -7076,7 +7025,7 @@ pub fn dn_expand(
7076 // loop invariants: p<end, dest<dend7025 // loop invariants: p<end, dest<dend
7077 if ((p[0] & 0xc0) != 0) {7026 if ((p[0] & 0xc0) != 0) {
7078 if (p + 1 == end) return error.InvalidDnsPacket;7027 if (p + 1 == end) return error.InvalidDnsPacket;
7079 const j = ((p[0] & @as(usize, 0x3f)) << 8) | p[1];7028 const j = @as(usize, p[0] & 0x3f) << 8 | p[1];
7080 if (len == std.math.maxInt(usize)) len = @intFromPtr(p) + 2 - @intFromPtr(comp_dn.ptr);7029 if (len == std.math.maxInt(usize)) len = @intFromPtr(p) + 2 - @intFromPtr(comp_dn.ptr);
7081 if (j >= msg.len) return error.InvalidDnsPacket;7030 if (j >= msg.len) return error.InvalidDnsPacket;
7082 p = msg.ptr + j;7031 p = msg.ptr + j;
...@@ -7130,7 +7079,7 @@ pub const SetSockOptError = error{...@@ -7130,7 +7079,7 @@ pub const SetSockOptError = error{
7130/// Set a socket's options.7079/// Set a socket's options.
7131pub fn setsockopt(fd: socket_t, level: u32, optname: u32, opt: []const u8) SetSockOptError!void {7080pub fn setsockopt(fd: socket_t, level: u32, optname: u32, opt: []const u8) SetSockOptError!void {
7132 if (builtin.os.tag == .windows) {7081 if (builtin.os.tag == .windows) {
7133 const rc = windows.ws2_32.setsockopt(fd, @as(i32, @intCast(level)), @as(i32, @intCast(optname)), opt.ptr, @as(i32, @intCast(opt.len)));7082 const rc = windows.ws2_32.setsockopt(fd, @intCast(level), @intCast(optname), opt.ptr, @intCast(opt.len));
7134 if (rc == windows.ws2_32.SOCKET_ERROR) {7083 if (rc == windows.ws2_32.SOCKET_ERROR) {
7135 switch (windows.ws2_32.WSAGetLastError()) {7084 switch (windows.ws2_32.WSAGetLastError()) {
7136 .WSANOTINITIALISED => unreachable,7085 .WSANOTINITIALISED => unreachable,
...@@ -7143,7 +7092,7 @@ pub fn setsockopt(fd: socket_t, level: u32, optname: u32, opt: []const u8) SetSo...@@ -7143,7 +7092,7 @@ pub fn setsockopt(fd: socket_t, level: u32, optname: u32, opt: []const u8) SetSo
7143 }7092 }
7144 return;7093 return;
7145 } else {7094 } else {
7146 switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @as(socklen_t, @intCast(opt.len))))) {7095 switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(opt.len)))) {
7147 .SUCCESS => {},7096 .SUCCESS => {},
7148 .BADF => unreachable, // always a race condition7097 .BADF => unreachable, // always a race condition
7149 .NOTSOCK => unreachable, // always a race condition7098 .NOTSOCK => unreachable, // always a race condition
...@@ -7180,7 +7129,7 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {...@@ -7180,7 +7129,7 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
7180 const getErrno = if (use_c) std.c.getErrno else linux.getErrno;7129 const getErrno = if (use_c) std.c.getErrno else linux.getErrno;
7181 const rc = sys.memfd_create(name, flags);7130 const rc = sys.memfd_create(name, flags);
7182 switch (getErrno(rc)) {7131 switch (getErrno(rc)) {
7183 .SUCCESS => return @as(fd_t, @intCast(rc)),7132 .SUCCESS => return @intCast(rc),
7184 .FAULT => unreachable, // name has invalid memory7133 .FAULT => unreachable, // name has invalid memory
7185 .INVAL => unreachable, // name/flags are faulty7134 .INVAL => unreachable, // name/flags are faulty
7186 .NFILE => return error.SystemFdQuotaExceeded,7135 .NFILE => return error.SystemFdQuotaExceeded,
...@@ -7330,7 +7279,7 @@ pub fn ioctl_SIOCGIFINDEX(fd: fd_t, ifr: *ifreq) IoCtl_SIOCGIFINDEX_Error!void {...@@ -7330,7 +7279,7 @@ pub fn ioctl_SIOCGIFINDEX(fd: fd_t, ifr: *ifreq) IoCtl_SIOCGIFINDEX_Error!void {
7330pub fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) !fd_t {7279pub fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) !fd_t {
7331 const rc = system.signalfd(fd, mask, flags);7280 const rc = system.signalfd(fd, mask, flags);
7332 switch (errno(rc)) {7281 switch (errno(rc)) {
7333 .SUCCESS => return @as(fd_t, @intCast(rc)),7282 .SUCCESS => return @intCast(rc),
7334 .BADF, .INVAL => unreachable,7283 .BADF, .INVAL => unreachable,
7335 .NFILE => return error.SystemFdQuotaExceeded,7284 .NFILE => return error.SystemFdQuotaExceeded,
7336 .NOMEM => return error.SystemResources,7285 .NOMEM => return error.SystemResources,
...@@ -7438,7 +7387,7 @@ pub fn prctl(option: PR, args: anytype) PrctlError!u31 {...@@ -7438,7 +7387,7 @@ pub fn prctl(option: PR, args: anytype) PrctlError!u31 {
74387387
7439 const rc = system.prctl(@intFromEnum(option), buf[0], buf[1], buf[2], buf[3]);7388 const rc = system.prctl(@intFromEnum(option), buf[0], buf[1], buf[2], buf[3]);
7440 switch (errno(rc)) {7389 switch (errno(rc)) {
7441 .SUCCESS => return @as(u31, @intCast(rc)),7390 .SUCCESS => return @intCast(rc),
7442 .ACCES => return error.AccessDenied,7391 .ACCES => return error.AccessDenied,
7443 .BADF => return error.InvalidFileDescriptor,7392 .BADF => return error.InvalidFileDescriptor,
7444 .FAULT => return error.InvalidAddress,7393 .FAULT => return error.InvalidAddress,
...@@ -7619,7 +7568,7 @@ pub fn perf_event_open(...@@ -7619,7 +7568,7 @@ pub fn perf_event_open(
7619) PerfEventOpenError!fd_t {7568) PerfEventOpenError!fd_t {
7620 const rc = linux.perf_event_open(attr, pid, cpu, group_fd, flags);7569 const rc = linux.perf_event_open(attr, pid, cpu, group_fd, flags);
7621 switch (errno(rc)) {7570 switch (errno(rc)) {
7622 .SUCCESS => return @as(fd_t, @intCast(rc)),7571 .SUCCESS => return @intCast(rc),
7623 .@"2BIG" => return error.TooBig,7572 .@"2BIG" => return error.TooBig,
7624 .ACCES => return error.PermissionDenied,7573 .ACCES => return error.PermissionDenied,
7625 .BADF => unreachable, // group_fd file descriptor is not valid.7574 .BADF => unreachable, // group_fd file descriptor is not valid.
...@@ -7654,7 +7603,7 @@ pub const TimerFdSetError = TimerFdGetError || error{Canceled};...@@ -7654,7 +7603,7 @@ pub const TimerFdSetError = TimerFdGetError || error{Canceled};
7654pub fn timerfd_create(clokid: i32, flags: linux.TFD) TimerFdCreateError!fd_t {7603pub fn timerfd_create(clokid: i32, flags: linux.TFD) TimerFdCreateError!fd_t {
7655 const rc = linux.timerfd_create(clokid, flags);7604 const rc = linux.timerfd_create(clokid, flags);
7656 return switch (errno(rc)) {7605 return switch (errno(rc)) {
7657 .SUCCESS => @as(fd_t, @intCast(rc)),7606 .SUCCESS => @intCast(rc),
7658 .INVAL => unreachable,7607 .INVAL => unreachable,
7659 .MFILE => return error.ProcessFdQuotaExceeded,7608 .MFILE => return error.ProcessFdQuotaExceeded,
7660 .NFILE => return error.SystemFdQuotaExceeded,7609 .NFILE => return error.SystemFdQuotaExceeded,
...@@ -7697,7 +7646,6 @@ pub fn timerfd_gettime(fd: i32) TimerFdGetError!linux.itimerspec {...@@ -7697,7 +7646,6 @@ pub fn timerfd_gettime(fd: i32) TimerFdGetError!linux.itimerspec {
7697pub const PtraceError = error{7646pub const PtraceError = error{
7698 DeviceBusy,7647 DeviceBusy,
7699 InputOutput,7648 InputOutput,
7700 Overflow,
7701 ProcessNotFound,7649 ProcessNotFound,
7702 PermissionDenied,7650 PermissionDenied,
7703} || UnexpectedError;7651} || UnexpectedError;
...@@ -7719,10 +7667,10 @@ pub fn ptrace(request: u32, pid: pid_t, addr: usize, signal: usize) PtraceError!...@@ -7719,10 +7667,10 @@ pub fn ptrace(request: u32, pid: pid_t, addr: usize, signal: usize) PtraceError!
7719 },7667 },
77207668
7721 .macos, .ios, .tvos, .watchos => switch (errno(darwin.ptrace(7669 .macos, .ios, .tvos, .watchos => switch (errno(darwin.ptrace(
7722 math.cast(i32, request) orelse return error.Overflow,7670 @intCast(request),
7723 pid,7671 pid,
7724 @as(?[*]u8, @ptrFromInt(addr)),7672 @ptrFromInt(addr),
7725 math.cast(i32, signal) orelse return error.Overflow,7673 @intCast(signal),
7726 ))) {7674 ))) {
7727 .SUCCESS => {},7675 .SUCCESS => {},
7728 .SRCH => error.ProcessNotFound,7676 .SRCH => error.ProcessNotFound,