authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-07-21 11:03:53+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-07-29 09:50:41+02:00
log4e5068c35cef5e1b3366aa05de60023b9fcd98e6
treea662d1be3f716c8f6bae6ee65d67289eb5a8c481
parent6eb9cb6f285d31c673aa9c175b5848f5a476fb07
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std: Stop supporting Linux/glibc versions older than declared in std.Target.


6 files changed, 16 insertions(+), 71 deletions(-)

lib/std/debug.zig+2-1
...@@ -747,7 +747,8 @@ pub const StackIterator = struct {...@@ -747,7 +747,8 @@ pub const StackIterator = struct {
747 .SUCCESS => return bytes_read == buf.len,747 .SUCCESS => return bytes_read == buf.len,
748 .FAULT => return false,748 .FAULT => return false,
749 .INVAL, .PERM, .SRCH => unreachable, // own pid is always valid749 .INVAL, .PERM, .SRCH => unreachable, // own pid is always valid
750 .NOMEM, .NOSYS => {},750 .NOMEM => {},
751 .NOSYS => {}, // QEMU is known not to implement this syscall.
751 else => unreachable, // unexpected752 else => unreachable, // unexpected
752 }753 }
753 var path_buf: [754 var path_buf: [
lib/std/fs/File.zig+1-20
...@@ -731,7 +731,7 @@ pub const Metadata = struct {...@@ -731,7 +731,7 @@ pub const Metadata = struct {
731731
732 /// Returns the time the file was created in nanoseconds since UTC 1970-01-01732 /// Returns the time the file was created in nanoseconds since UTC 1970-01-01
733 /// On Windows, this cannot return null733 /// On Windows, this cannot return null
734 /// On Linux, this returns null if the filesystem does not support creation times, or if the kernel is older than 4.11734 /// On Linux, this returns null if the filesystem does not support creation times
735 /// On Unices, this returns null if the filesystem or OS does not support creation times735 /// On Unices, this returns null if the filesystem or OS does not support creation times
736 /// On MacOS, this returns the ctime if the filesystem does not support creation times; this is insanity, and yet another reason to hate on Apple736 /// On MacOS, this returns the ctime if the filesystem does not support creation times; this is insanity, and yet another reason to hate on Apple
737 pub fn created(self: Self) ?i128 {737 pub fn created(self: Self) ?i128 {
...@@ -822,7 +822,6 @@ pub const MetadataUnix = struct {...@@ -822,7 +822,6 @@ pub const MetadataUnix = struct {
822};822};
823823
824/// `MetadataUnix`, but using Linux's `statx` syscall.824/// `MetadataUnix`, but using Linux's `statx` syscall.
825/// On Linux versions below 4.11, `statx` will be filled with data from stat.
826pub const MetadataLinux = struct {825pub const MetadataLinux = struct {
827 statx: std.os.linux.Statx,826 statx: std.os.linux.Statx,
828827
...@@ -1017,24 +1016,6 @@ pub fn metadata(self: File) MetadataError!Metadata {...@@ -1017,24 +1016,6 @@ pub fn metadata(self: File) MetadataError!Metadata {
10171016
1018 switch (posix.errno(rcx)) {1017 switch (posix.errno(rcx)) {
1019 .SUCCESS => {},1018 .SUCCESS => {},
1020 // NOSYS happens when `statx` is unsupported, which is the case on kernel versions before 4.11
1021 // Here, we call `fstat` and fill `stx` with the data we need
1022 .NOSYS => {
1023 const st = try posix.fstat(self.handle);
1024
1025 stx.mode = @as(u16, @intCast(st.mode));
1026
1027 // Hacky conversion from timespec to statx_timestamp
1028 stx.atime = std.mem.zeroes(l.statx_timestamp);
1029 stx.atime.sec = st.atim.sec;
1030 stx.atime.nsec = @as(u32, @intCast(st.atim.nsec)); // Guaranteed to succeed (nsec is always below 10^9)
1031
1032 stx.mtime = std.mem.zeroes(l.statx_timestamp);
1033 stx.mtime.sec = st.mtim.sec;
1034 stx.mtime.nsec = @as(u32, @intCast(st.mtim.nsec));
1035
1036 stx.mask = l.STATX_BASIC_STATS | l.STATX_MTIME;
1037 },
1038 .BADF => unreachable,1019 .BADF => unreachable,
1039 .FAULT => unreachable,1020 .FAULT => unreachable,
1040 .NOMEM => return error.SystemResources,1021 .NOMEM => return error.SystemResources,
lib/std/os/linux.zig+8-11
...@@ -1890,17 +1890,14 @@ pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: u32) usi...@@ -1890,17 +1890,14 @@ pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *Stat, flags: u32) usi
1890}1890}
18911891
1892pub fn statx(dirfd: i32, path: [*:0]const u8, flags: u32, mask: u32, statx_buf: *Statx) usize {1892pub fn statx(dirfd: i32, path: [*:0]const u8, flags: u32, mask: u32, statx_buf: *Statx) usize {
1893 if (@hasField(SYS, "statx")) {1893 return syscall5(
1894 return syscall5(1894 .statx,
1895 .statx,1895 @as(usize, @bitCast(@as(isize, dirfd))),
1896 @as(usize, @bitCast(@as(isize, dirfd))),1896 @intFromPtr(path),
1897 @intFromPtr(path),1897 flags,
1898 flags,1898 mask,
1899 mask,1899 @intFromPtr(statx_buf),
1900 @intFromPtr(statx_buf),1900 );
1901 );
1902 }
1903 return @as(usize, @bitCast(-@as(isize, @intFromEnum(E.NOSYS))));
1904}1901}
19051902
1906pub fn listxattr(path: [*:0]const u8, list: [*]u8, size: usize) usize {1903pub fn listxattr(path: [*:0]const u8, list: [*]u8, size: usize) usize {
lib/std/os/linux/test.zig-2
...@@ -79,8 +79,6 @@ test "statx" {...@@ -79,8 +79,6 @@ test "statx" {
79 var statx_buf: linux.Statx = undefined;79 var statx_buf: linux.Statx = undefined;
80 switch (linux.E.init(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {80 switch (linux.E.init(linux.statx(file.handle, "", linux.AT.EMPTY_PATH, linux.STATX_BASIC_STATS, &statx_buf))) {
81 .SUCCESS => {},81 .SUCCESS => {},
82 // The statx syscall was only introduced in linux 4.11
83 .NOSYS => return error.SkipZigTest,
84 else => unreachable,82 else => unreachable,
85 }83 }
8684
lib/std/posix.zig+4-32
...@@ -615,7 +615,6 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {...@@ -615,7 +615,6 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
615 .INVAL => unreachable,615 .INVAL => unreachable,
616 .FAULT => unreachable,616 .FAULT => unreachable,
617 .INTR => continue,617 .INTR => continue,
618 .NOSYS => return getRandomBytesDevURandom(buf),
619 else => return unexpectedErrno(err),618 else => return unexpectedErrno(err),
620 }619 }
621 }620 }
...@@ -4534,7 +4533,6 @@ pub const FanotifyInitError = error{...@@ -4534,7 +4533,6 @@ pub const FanotifyInitError = error{
4534 ProcessFdQuotaExceeded,4533 ProcessFdQuotaExceeded,
4535 SystemFdQuotaExceeded,4534 SystemFdQuotaExceeded,
4536 SystemResources,4535 SystemResources,
4537 OperationNotSupported,
4538 PermissionDenied,4536 PermissionDenied,
4539} || UnexpectedError;4537} || UnexpectedError;
45404538
...@@ -4546,7 +4544,6 @@ pub fn fanotify_init(flags: std.os.linux.fanotify.InitFlags, event_f_flags: u32)...@@ -4546,7 +4544,6 @@ pub fn fanotify_init(flags: std.os.linux.fanotify.InitFlags, event_f_flags: u32)
4546 .MFILE => return error.ProcessFdQuotaExceeded,4544 .MFILE => return error.ProcessFdQuotaExceeded,
4547 .NFILE => return error.SystemFdQuotaExceeded,4545 .NFILE => return error.SystemFdQuotaExceeded,
4548 .NOMEM => return error.SystemResources,4546 .NOMEM => return error.SystemResources,
4549 .NOSYS => return error.OperationNotSupported,
4550 .PERM => return error.PermissionDenied,4547 .PERM => return error.PermissionDenied,
4551 else => |err| return unexpectedErrno(err),4548 else => |err| return unexpectedErrno(err),
4552 }4549 }
...@@ -4559,7 +4556,6 @@ pub const FanotifyMarkError = error{...@@ -4559,7 +4556,6 @@ pub const FanotifyMarkError = error{
4559 FileNotFound,4556 FileNotFound,
4560 SystemResources,4557 SystemResources,
4561 UserMarkQuotaExceeded,4558 UserMarkQuotaExceeded,
4562 NotImplemented,
4563 NotDir,4559 NotDir,
4564 OperationNotSupported,4560 OperationNotSupported,
4565 PermissionDenied,4561 PermissionDenied,
...@@ -4600,7 +4596,6 @@ pub fn fanotify_markZ(...@@ -4600,7 +4596,6 @@ pub fn fanotify_markZ(
4600 .NOENT => return error.FileNotFound,4596 .NOENT => return error.FileNotFound,
4601 .NOMEM => return error.SystemResources,4597 .NOMEM => return error.SystemResources,
4602 .NOSPC => return error.UserMarkQuotaExceeded,4598 .NOSPC => return error.UserMarkQuotaExceeded,
4603 .NOSYS => return error.NotImplemented,
4604 .NOTDIR => return error.NotDir,4599 .NOTDIR => return error.NotDir,
4605 .OPNOTSUPP => return error.OperationNotSupported,4600 .OPNOTSUPP => return error.OperationNotSupported,
4606 .PERM => return error.PermissionDenied,4601 .PERM => return error.PermissionDenied,
...@@ -6183,13 +6178,6 @@ pub fn sendfile(...@@ -6183,13 +6178,6 @@ pub fn sendfile(
61836178
6184 switch (native_os) {6179 switch (native_os) {
6185 .linux => sf: {6180 .linux => sf: {
6186 // sendfile() first appeared in Linux 2.2, glibc 2.1.
6187 const call_sf = comptime if (builtin.link_libc)
6188 std.c.versionCheck(.{ .major = 2, .minor = 1, .patch = 0 })
6189 else
6190 builtin.os.version_range.linux.range.max.order(.{ .major = 2, .minor = 2, .patch = 0 }) != .lt;
6191 if (!call_sf) break :sf;
6192
6193 if (headers.len != 0) {6181 if (headers.len != 0) {
6194 const amt = try writev(out_fd, headers);6182 const amt = try writev(out_fd, headers);
6195 total_written += amt;6183 total_written += amt;
...@@ -6223,14 +6211,14 @@ pub fn sendfile(...@@ -6223,14 +6211,14 @@ pub fn sendfile(
6223 .OVERFLOW => unreachable, // We avoid passing too large of a `count`.6211 .OVERFLOW => unreachable, // We avoid passing too large of a `count`.
6224 .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket6212 .NOTCONN => return error.BrokenPipe, // `out_fd` is an unconnected socket
62256213
6226 .INVAL, .NOSYS => {6214 .INVAL => {
6227 // EINVAL could be any of the following situations:6215 // EINVAL could be any of the following situations:
6228 // * Descriptor is not valid or locked6216 // * Descriptor is not valid or locked
6229 // * an mmap(2)-like operation is not available for in_fd6217 // * an mmap(2)-like operation is not available for in_fd
6230 // * count is negative6218 // * count is negative
6231 // * out_fd has the APPEND flag set6219 // * out_fd has the APPEND flag set
6232 // Because of the "mmap(2)-like operation" possibility, we fall back to doing read/write6220 // Because of the "mmap(2)-like operation" possibility, we fall back to doing read/write
6233 // manually, the same as ENOSYS.6221 // manually.
6234 break :sf;6222 break :sf;
6235 },6223 },
6236 .AGAIN => return error.WouldBlock,6224 .AGAIN => return error.WouldBlock,
...@@ -6456,21 +6444,15 @@ pub const CopyFileRangeError = error{...@@ -6456,21 +6444,15 @@ pub const CopyFileRangeError = error{
6456/// `flags` has different meanings per operating system; refer to the respective man pages.6444/// `flags` has different meanings per operating system; refer to the respective man pages.
6457///6445///
6458/// These systems support in-kernel data copying:6446/// These systems support in-kernel data copying:
6459/// * Linux 4.5 (cross-filesystem 5.3)6447/// * Linux (cross-filesystem from version 5.3)
6460/// * FreeBSD 13.06448/// * FreeBSD 13.0
6461///6449///
6462/// Other systems fall back to calling `pread` / `pwrite`.6450/// Other systems fall back to calling `pread` / `pwrite`.
6463///6451///
6464/// Maximum offsets on Linux and FreeBSD are `maxInt(i64)`.6452/// Maximum offsets on Linux and FreeBSD are `maxInt(i64)`.
6465pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize {6453pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize {
6466 const global = struct {
6467 var has_copy_file_range = true;
6468 };
6469
6470 if ((comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) or6454 if ((comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) or
6471 ((comptime builtin.os.isAtLeast(.linux, .{ .major = 4, .minor = 5, .patch = 0 }) orelse false and6455 (comptime builtin.os.tag == .linux and std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 })))
6472 std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 })) and
6473 @atomicLoad(bool, &global.has_copy_file_range, .monotonic)))
6474 {6456 {
6475 var off_in_copy: i64 = @bitCast(off_in);6457 var off_in_copy: i64 = @bitCast(off_in);
6476 var off_out_copy: i64 = @bitCast(off_out);6458 var off_out_copy: i64 = @bitCast(off_out);
...@@ -6504,10 +6486,6 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len...@@ -6504,10 +6486,6 @@ pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len
6504 .PERM => return error.PermissionDenied,6486 .PERM => return error.PermissionDenied,
6505 .TXTBSY => return error.SwapFile,6487 .TXTBSY => return error.SwapFile,
6506 .XDEV => break, // support for cross-filesystem copy added in Linux 5.3, use fallback6488 .XDEV => break, // support for cross-filesystem copy added in Linux 5.3, use fallback
6507 .NOSYS => {
6508 @atomicStore(bool, &global.has_copy_file_range, false, .monotonic);
6509 break;
6510 },
6511 else => |err| return unexpectedErrno(err),6489 else => |err| return unexpectedErrno(err),
6512 }6490 }
6513 }6491 }
...@@ -6775,10 +6753,6 @@ pub const MemFdCreateError = error{...@@ -6775,10 +6753,6 @@ pub const MemFdCreateError = error{
6775 OutOfMemory,6753 OutOfMemory,
6776 /// Either the name provided exceeded `NAME_MAX`, or invalid flags were passed.6754 /// Either the name provided exceeded `NAME_MAX`, or invalid flags were passed.
6777 NameTooLong,6755 NameTooLong,
6778
6779 /// memfd_create is available in Linux 3.17 and later. This error is returned
6780 /// for older kernel versions.
6781 SystemOutdated,
6782} || UnexpectedError;6756} || UnexpectedError;
67836757
6784pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {6758pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
...@@ -6795,7 +6769,6 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {...@@ -6795,7 +6769,6 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
6795 .NFILE => return error.SystemFdQuotaExceeded,6769 .NFILE => return error.SystemFdQuotaExceeded,
6796 .MFILE => return error.ProcessFdQuotaExceeded,6770 .MFILE => return error.ProcessFdQuotaExceeded,
6797 .NOMEM => return error.OutOfMemory,6771 .NOMEM => return error.OutOfMemory,
6798 .NOSYS => return error.SystemOutdated,
6799 else => |err| return unexpectedErrno(err),6772 else => |err| return unexpectedErrno(err),
6800 }6773 }
6801 },6774 },
...@@ -6915,7 +6888,6 @@ pub fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) !fd_t {...@@ -6915,7 +6888,6 @@ pub fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) !fd_t {
6915 .NOMEM => return error.SystemResources,6888 .NOMEM => return error.SystemResources,
6916 .MFILE => return error.ProcessResources,6889 .MFILE => return error.ProcessResources,
6917 .NODEV => return error.InodeMountFail,6890 .NODEV => return error.InodeMountFail,
6918 .NOSYS => return error.SystemOutdated,
6919 else => |err| return unexpectedErrno(err),6891 else => |err| return unexpectedErrno(err),
6920 }6892 }
6921}6893}
lib/std/posix/test.zig+1-5
...@@ -580,11 +580,7 @@ test "memfd_create" {...@@ -580,11 +580,7 @@ test "memfd_create" {
580 else => return error.SkipZigTest,580 else => return error.SkipZigTest,
581 }581 }
582582
583 const fd = posix.memfd_create("test", 0) catch |err| switch (err) {583 const fd = try posix.memfd_create("test", 0);
584 // Related: https://github.com/ziglang/zig/issues/4019
585 error.SystemOutdated => return error.SkipZigTest,
586 else => |e| return e,
587 };
588 defer posix.close(fd);584 defer posix.close(fd);
589 try expect((try posix.write(fd, "test")) == 4);585 try expect((try posix.write(fd, "test")) == 4);
590 try posix.lseek_SET(fd, 0);586 try posix.lseek_SET(fd, 0);