From a6626802f9ee080616064aff0bc3f0f2709488c3 Mon Sep 17 00:00:00 2001 From: luna Date: Wed, 22 Jul 2020 18:26:27 -0300 Subject: [PATCH] Add signalfd support (#5322) * add signalfd_siginfo to linux bits * Cast sigaddset's shift value to u5 * linux: add signalfd4 * os: add signalfd --- lib/std/os.zig | 14 ++++++++++++++ lib/std/os/bits/linux.zig | 25 +++++++++++++++++++++++++ lib/std/os/linux.zig | 15 ++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/lib/std/os.zig b/lib/std/os.zig index 3e05ac41e..1665a2efa 100644 --- a/lib/std/os.zig +++ b/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), + } +} diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig index 64832673f..41d681554 100644 --- a/lib/std/os/bits/linux.zig +++ b/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; diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 3b8df3d17..15d6e53c1 100644 --- a/lib/std/os/linux.zig +++ b/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");