Commit a6626802f9

luna <git@l4.pm>
2020-07-22 23:26:27
Add signalfd support (#5322)
* add signalfd_siginfo to linux bits * Cast sigaddset's shift value to u5 * linux: add signalfd4 * os: add signalfd
1 parent 9505bb7
Changed files (3)
lib
lib/std/os/bits/linux.zig
@@ -840,6 +840,31 @@ pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
 
 pub const empty_sigset = [_]u32{0} ** sigset_t.len;
 
+pub const signalfd_siginfo = extern struct {
+    signo: u32,
+    errno: i32,
+    code: i32,
+    pid: u32,
+    uid: u32,
+    fd: i32,
+    tid: u32,
+    band: u32,
+    overrun: u32,
+    trapno: u32,
+    status: i32,
+    int: i32,
+    ptr: u64,
+    utime: u64,
+    stime: u64,
+    addr: u64,
+    addr_lsb: u16,
+    __pad2: u16,
+    syscall: i32,
+    call_addr: u64,
+    arch: u32,
+    __pad: [28]u8,
+};
+
 pub const in_port_t = u16;
 pub const sa_family_t = u16;
 pub const socklen_t = u32;
lib/std/os/linux.zig
@@ -811,7 +811,10 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
 
 pub fn sigaddset(set: *sigset_t, sig: u6) void {
     const s = sig - 1;
-    (set.*)[@intCast(usize, s) / usize.bit_count] |= @intCast(usize, 1) << (s & (usize.bit_count - 1));
+    // shift in musl: s&8*sizeof *set->__bits-1
+    const shift = @intCast(u5, s & (usize.bit_count - 1));
+    const val = @intCast(u32, 1) << shift;
+    (set.*)[@intCast(usize, s) / usize.bit_count] |= val;
 }
 
 pub fn sigismember(set: *const sigset_t, sig: u6) bool {
@@ -1197,6 +1200,16 @@ pub fn ioctl(fd: fd_t, request: u32, arg: usize) usize {
     return syscall3(.ioctl, @bitCast(usize, @as(isize, fd)), request, arg);
 }
 
+pub fn signalfd4(fd: fd_t, mask: *const sigset_t, flags: i32) usize {
+    return syscall4(
+        .signalfd4,
+        @bitCast(usize, @as(isize, fd)),
+        @ptrToInt(mask),
+        @bitCast(usize, @as(usize, NSIG / 8)),
+        @intCast(usize, flags),
+    );
+}
+
 test "" {
     if (builtin.os.tag == .linux) {
         _ = @import("linux/test.zig");
lib/std/os.zig
@@ -5133,3 +5133,17 @@ pub fn ioctl_SIOCGIFINDEX(fd: fd_t, ifr: *ifreq) IoCtl_SIOCGIFINDEX_Error!void {
         }
     }
 }
+
+pub fn signalfd(fd: fd_t, mask: *const sigset_t, flags: i32) !fd_t {
+    const rc = system.signalfd4(fd, mask, flags);
+    switch (errno(rc)) {
+        0 => return @intCast(fd_t, rc),
+        EBADF, EINVAL => unreachable,
+        ENFILE => return error.SystemFdQuotaExceeded,
+        ENOMEM => return error.SystemResources,
+        EMFILE => return error.ProcessResources,
+        ENODEV => return error.InodeMountFail,
+        ENOSYS => return error.SystemOutdated,
+        else => |err| return std.os.unexpectedErrno(err),
+    }
+}