Something went wrong. Try again.
various tools I have been using throughout the years
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283const signals = @import("signals.zig");const std = @import("std");const terminal = @import("terminal.zig");
pub const Command = enum { Pause, Quit, Reset,};
pub const Poller = struct { stdin_fd: std.posix.fd_t, signals_fd: std.posix.fd_t, terminal: ?terminal.Terminal,
pub fn init(allocator: std.mem.Allocator) !Poller { _ = allocator; const opt_terminal = blk: { break :blk terminal.Terminal.init() catch |err| { std.log.debug("failed to init terminal: {any}", .{err}); break :blk null; }; }; errdefer { if (opt_terminal) |terminal_| { terminal_.deinit(); } }
const signals_file = try signals.open(); const signals_fd = signals_file.handle;
return Poller{ .terminal = opt_terminal, .stdin_fd = std.Io.File.stdin().handle, .signals_fd = signals_fd, }; }
pub fn interactive(self: *Poller) bool { return self.terminal != null; }
pub fn deinit(self: *Poller) void { if (self.terminal) |terminal_| terminal_.deinit(); }
pub fn pollTimeout(self: *Poller, nanoseconds: u64) !?Command { var fds = [2]std.posix.pollfd{ .{ .fd = self.stdin_fd, .events = std.posix.POLL.IN, .revents = 0 }, .{ .fd = self.signals_fd, .events = std.posix.POLL.IN, .revents = 0 }, };
const timeout_ms = @as(i32, @intCast(@divTrunc(nanoseconds, std.time.ns_per_ms))); const n = try std.posix.poll(&fds, timeout_ms); if (n == 0) return null;
if (fds[0].revents & std.posix.POLL.IN != 0) { var buf: [1]u8 = undefined; const bytes_read = try std.posix.read(self.stdin_fd, &buf); if (bytes_read > 0) { switch (buf[0]) { 'p' => return Command.Pause, 'q' => return Command.Quit, 'r' => return Command.Reset, else => {}, } } }
if (fds[1].revents & std.posix.POLL.IN != 0) { const signo = try signals.readSignal(self.signals_fd); switch (signo) { std.posix.SIG.USR1 => return Command.Pause, std.posix.SIG.USR2 => return Command.Reset, else => unreachable, } }
return null; }};