signals.zig (2007B)
1 const std = @import("std"); 2 const builtin = @import("builtin"); 3 4 var signal_pipe: [2]std.posix.fd_t = undefined; 5 6 fn signalHandler(sig: i32) callconv(.c) void { 7 const s: i32 = sig; 8 _ = std.c.write(signal_pipe[1], std.mem.asBytes(&s), @sizeOf(i32)); 9 } 10 11 pub fn open() !std.Io.File { 12 if (builtin.os.tag == .linux) { 13 var mask = std.posix.sigemptyset(); 14 std.posix.sigaddset(&mask, std.posix.SIG.USR1); 15 std.posix.sigaddset(&mask, std.posix.SIG.USR2); 16 17 std.posix.sigprocmask(std.posix.SIG.BLOCK, &mask, null); 18 19 const fd = try std.posix.signalfd(-1, &mask, std.os.linux.SFD.NONBLOCK); 20 return .{ .handle = fd, .flags = .{ .nonblocking = false } }; 21 } else { 22 const rc = std.c.pipe(&signal_pipe); 23 switch (std.posix.errno(@intCast(rc))) { 24 .SUCCESS => {}, 25 else => |err| return std.posix.unexpectedErrno(err), 26 } 27 28 const sa = std.posix.Sigaction{ 29 .handler = .{ .handler = signalHandler }, 30 .mask = std.posix.sigemptyset(), 31 .flags = 0, 32 }; 33 34 std.posix.sigaction(std.posix.SIG.USR1, &sa, null); 35 std.posix.sigaction(std.posix.SIG.USR2, &sa, null); 36 37 return .{ .handle = signal_pipe[0], .flags = .{ .nonblocking = false } }; 38 } 39 } 40 41 pub fn readSignal(fd: std.posix.fd_t) !std.posix.SIG { 42 if (builtin.os.tag == .linux) { 43 var buf: [@sizeOf(std.os.linux.signalfd_siginfo)]u8 align(@alignOf(std.os.linux.signalfd_siginfo)) = undefined; 44 const n = try std.posix.read(fd, &buf); 45 if (n == 0) return error.Unexpected; 46 const siginfo: *const std.os.linux.signalfd_siginfo = @ptrCast(@alignCast(&buf)); 47 return @enumFromInt(siginfo.signo); 48 } else { 49 var buf: [4]u8 = undefined; 50 const n = try std.posix.read(fd, &buf); 51 if (n < 4) return error.Unexpected; 52 var result: i32 = undefined; 53 @memcpy(std.mem.asBytes(&result), &buf); 54 return @enumFromInt(result); 55 } 56 }