authorgravatar for michaldrozd@protonmail.chMichał Drozd <michaldrozd@protonmail.ch> 2024-08-23 16:21:19+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-08-23 14:21:19+00:00
log206e5e4d7d879d006c130aa8dbd3b769da356c11
tree9c11b6a65d41e1e54199c07806cac0b03163cf61
parentdc72138b91f0a6759af686bca84d73b526d882db
signaturebadge-check Signed by PGP key B5690EEEBB952194

std.os.linux: Fix bunch of compilation errors (#21138)

* Correct layout of IntInfo according to https://www.kernel.org/doc/html/latest/bpf/btf.html#btf-kind-int * Fix VFS errors * Fix std.os.linux.sendmmsg * Fix std.os.linux.sigismember. Add tests * Fix futex2 functions

3 files changed, 38 insertions(+), 18 deletions(-)

lib/std/os/linux.zig+19-17
......@@ -630,12 +630,13 @@ pub fn futex2_waitv(
630630 nr_futexes,
631631 flags,
632632 @intFromPtr(timeout),
633 @bitCast(@as(isize, clockid)),
633 @bitCast(@as(isize, @intFromEnum(clockid))),
634634 );
635635}
636636
637637/// Wait on a futex.
638/// Identical to `FUTEX.WAIT`, except it is part of the futex2 family of calls.
638/// Identical to the traditional `FUTEX.FUTEX_WAIT_BITSET` op, except it is part of the
639/// futex2 familiy of calls.
639640pub fn futex2_wait(
640641 /// Address of the futex to wait on.
641642 uaddr: *const anyopaque,
......@@ -646,7 +647,7 @@ pub fn futex2_wait(
646647 /// `FUTEX2` flags.
647648 flags: u32,
648649 /// Optional absolute timeout.
649 timeout: *const timespec,
650 timeout: ?*const timespec,
650651 /// Clock to be used for the timeout, realtime or monotonic.
651652 clockid: clockid_t,
652653) usize {
......@@ -657,15 +658,16 @@ pub fn futex2_wait(
657658 mask,
658659 flags,
659660 @intFromPtr(timeout),
660 @bitCast(@as(isize, clockid)),
661 @bitCast(@as(isize, @intFromEnum(clockid))),
661662 );
662663}
663664
664665/// Wake a number of futexes.
665/// Identical to `FUTEX.WAKE`, except it is part of the futex2 family of calls.
666/// Identical to the traditional `FUTEX.FUTEX_WAIT_BITSET` op, except it is part of the
667/// futex2 family of calls.
666668pub fn futex2_wake(
667669 /// Address of the futex(es) to wake.
668 uaddr: [*]const anyopaque,
670 uaddr: *const anyopaque,
669671 /// Bitmask
670672 mask: usize,
671673 /// Number of the futexes to wake.
......@@ -1683,7 +1685,7 @@ pub fn sigaddset(set: *sigset_t, sig: u6) void {
16831685
16841686pub fn sigismember(set: *const sigset_t, sig: u6) bool {
16851687 const s = sig - 1;
1686 return ((set.*)[@as(usize, @intCast(s)) / usize_bits] & (@as(usize, @intCast(1)) << (s & (usize_bits - 1)))) != 0;
1688 return ((set.*)[@as(usize, @intCast(s)) / usize_bits] & (@as(usize, @intCast(1)) << @intCast(s & (usize_bits - 1)))) != 0;
16871689}
16881690
16891691pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
......@@ -1740,31 +1742,31 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize
17401742 var next_unsent: usize = 0;
17411743 for (msgvec[0..kvlen], 0..) |*msg, i| {
17421744 var size: i32 = 0;
1743 const msg_iovlen = @as(usize, @intCast(msg.msg_hdr.msg_iovlen)); // kernel side this is treated as unsigned
1744 for (msg.msg_hdr.msg_iov[0..msg_iovlen]) |iov| {
1745 const msg_iovlen = @as(usize, @intCast(msg.hdr.iovlen)); // kernel side this is treated as unsigned
1746 for (msg.hdr.iov[0..msg_iovlen]) |iov| {
17451747 if (iov.len > std.math.maxInt(i32) or @addWithOverflow(size, @as(i32, @intCast(iov.len)))[1] != 0) {
17461748 // batch-send all messages up to the current message
17471749 if (next_unsent < i) {
17481750 const batch_size = i - next_unsent;
17491751 const r = syscall4(.sendmmsg, @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(&msgvec[next_unsent]), batch_size, flags);
1750 if (E.init(r) != 0) return next_unsent;
1752 if (E.init(r) != .SUCCESS) return next_unsent;
17511753 if (r < batch_size) return next_unsent + r;
17521754 }
17531755 // send current message as own packet
1754 const r = sendmsg(fd, &msg.msg_hdr, flags);
1755 if (E.init(r) != 0) return r;
1756 const r = sendmsg(fd, &msg.hdr, flags);
1757 if (E.init(r) != .SUCCESS) return r;
17561758 // Linux limits the total bytes sent by sendmsg to INT_MAX, so this cast is safe.
1757 msg.msg_len = @as(u32, @intCast(r));
1759 msg.len = @as(u32, @intCast(r));
17581760 next_unsent = i + 1;
17591761 break;
17601762 }
1761 size += iov.len;
1763 size += @intCast(iov.len);
17621764 }
17631765 }
17641766 if (next_unsent < kvlen or next_unsent == 0) { // want to make sure at least one syscall occurs (e.g. to trigger MSG.EOR)
17651767 const batch_size = kvlen - next_unsent;
17661768 const r = syscall4(.sendmmsg, @as(usize, @bitCast(@as(isize, fd))), @intFromPtr(&msgvec[next_unsent]), batch_size, flags);
1767 if (E.init(r) != 0) return r;
1769 if (E.init(r) != .SUCCESS) return r;
17681770 return next_unsent + r;
17691771 }
17701772 return kvlen;
......@@ -5095,7 +5097,7 @@ pub const epoll_event = extern struct {
50955097
50965098pub const VFS_CAP_REVISION_MASK = 0xFF000000;
50975099pub const VFS_CAP_REVISION_SHIFT = 24;
5098pub const VFS_CAP_FLAGS_MASK = ~VFS_CAP_REVISION_MASK;
5100pub const VFS_CAP_FLAGS_MASK = ~@as(u32, VFS_CAP_REVISION_MASK);
50995101pub const VFS_CAP_FLAGS_EFFECTIVE = 0x000001;
51005102
51015103pub const VFS_CAP_REVISION_1 = 0x01000000;
......@@ -5113,7 +5115,7 @@ pub const VFS_CAP_REVISION = VFS_CAP_REVISION_2;
51135115pub const vfs_cap_data = extern struct {
51145116 //all of these are mandated as little endian
51155117 //when on disk.
5116 const Data = struct {
5118 const Data = extern struct {
51175119 permitted: u32,
51185120 inheritable: u32,
51195121 };
lib/std/os/linux/bpf/btf.zig+2-1
......@@ -83,13 +83,14 @@ pub const Kind = enum(u5) {
8383/// int kind is followed by this struct
8484pub const IntInfo = packed struct(u32) {
8585 bits: u8,
86 unused: u8,
86 reserved_1: u8,
8787 offset: u8,
8888 encoding: enum(u4) {
8989 signed = 1 << 0,
9090 char = 1 << 1,
9191 boolean = 1 << 2,
9292 },
93 reserved_2: u4,
9394};
9495
9596test "IntInfo is 32 bits" {
lib/std/os/linux/test.zig+17
......@@ -125,6 +125,23 @@ test "fadvise" {
125125 try expectEqual(@as(usize, 0), ret);
126126}
127127
128test "sigset_t" {
129 var sigset = linux.empty_sigset;
130
131 try expectEqual(linux.sigismember(&sigset, linux.SIG.USR1), false);
132 try expectEqual(linux.sigismember(&sigset, linux.SIG.USR2), false);
133
134 linux.sigaddset(&sigset, linux.SIG.USR1);
135
136 try expectEqual(linux.sigismember(&sigset, linux.SIG.USR1), true);
137 try expectEqual(linux.sigismember(&sigset, linux.SIG.USR2), false);
138
139 linux.sigaddset(&sigset, linux.SIG.USR2);
140
141 try expectEqual(linux.sigismember(&sigset, linux.SIG.USR1), true);
142 try expectEqual(linux.sigismember(&sigset, linux.SIG.USR2), true);
143}
144
128145test {
129146 _ = linux.IoUring;
130147}