tty: use simple os.read loop instead of xev
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
This commit is contained in:
parent
b9564b7db8
commit
48362a307c
2 changed files with 24 additions and 54 deletions
|
@ -15,7 +15,14 @@ pub fn main() !void {
|
||||||
var tty = try Tty.init();
|
var tty = try Tty.init();
|
||||||
defer tty.deinit();
|
defer tty.deinit();
|
||||||
|
|
||||||
try tty.run();
|
const pipe = try std.os.pipe();
|
||||||
|
// run our tty read loop in it's own thread
|
||||||
|
const read_thread = try std.Thread.spawn(.{}, Tty.run, .{ &tty, pipe[0] });
|
||||||
|
try read_thread.setName("tty");
|
||||||
|
|
||||||
|
std.time.sleep(100_000_000_0);
|
||||||
|
_ = try std.os.write(pipe[1], "q");
|
||||||
|
read_thread.join();
|
||||||
|
|
||||||
try stdout.print("Run `zig build test` to run the tests.\n", .{});
|
try stdout.print("Run `zig build test` to run the tests.\n", .{});
|
||||||
|
|
||||||
|
|
|
@ -12,33 +12,17 @@ termios: os.termios,
|
||||||
/// The file descriptor we are using for I/O
|
/// The file descriptor we are using for I/O
|
||||||
fd: os.fd_t,
|
fd: os.fd_t,
|
||||||
|
|
||||||
/// Stream attached to our fd
|
|
||||||
stream: xev.Stream,
|
|
||||||
|
|
||||||
/// event loop
|
|
||||||
loop: xev.Loop,
|
|
||||||
|
|
||||||
read_buffer: [1024]u8 = undefined,
|
|
||||||
|
|
||||||
/// initializes a Tty instance by opening /dev/tty and "making it raw"
|
/// initializes a Tty instance by opening /dev/tty and "making it raw"
|
||||||
pub fn init() !Tty {
|
pub fn init() !Tty {
|
||||||
// Open our tty
|
// Open our tty
|
||||||
const fd = try os.open("/dev/tty", os.system.O.RDWR, 0);
|
const fd = try os.open("/dev/tty", os.system.O.RDWR, 0);
|
||||||
|
|
||||||
// Initialize the stream
|
|
||||||
const stream = xev.Stream.initFd(fd);
|
|
||||||
|
|
||||||
// Initialize event loop
|
|
||||||
const loop = try xev.Loop.init(.{});
|
|
||||||
|
|
||||||
// Set the termios of the tty
|
// Set the termios of the tty
|
||||||
const termios = try makeRaw(fd);
|
const termios = try makeRaw(fd);
|
||||||
|
|
||||||
return Tty{
|
return Tty{
|
||||||
.fd = fd,
|
.fd = fd,
|
||||||
.stream = stream,
|
|
||||||
.termios = termios,
|
.termios = termios,
|
||||||
.loop = loop,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,47 +32,26 @@ pub fn deinit(self: *Tty) void {
|
||||||
log.err("couldn't restore terminal: {}", .{err});
|
log.err("couldn't restore terminal: {}", .{err});
|
||||||
};
|
};
|
||||||
os.close(self.fd);
|
os.close(self.fd);
|
||||||
self.stream.deinit();
|
|
||||||
self.loop.deinit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// read input from the tty
|
/// read input from the tty
|
||||||
pub fn run(self: *Tty) !void {
|
pub fn run(self: *Tty, quit: os.fd_t) !void {
|
||||||
var c_stream: xev.Completion = undefined;
|
defer os.close(quit);
|
||||||
|
var buf: [1024]u8 = undefined;
|
||||||
// Initialize our read event
|
var pollfds: [2]std.os.pollfd = .{
|
||||||
self.stream.read(
|
.{ .fd = self.fd, .events = std.os.POLL.IN, .revents = undefined },
|
||||||
&self.loop,
|
.{ .fd = quit, .events = std.os.POLL.IN, .revents = undefined },
|
||||||
&c_stream,
|
};
|
||||||
.{ .slice = self.read_buffer[0..] },
|
while (true) {
|
||||||
Tty,
|
_ = try std.os.poll(&pollfds, -1);
|
||||||
self,
|
if (pollfds[1].revents & std.os.POLL.IN != 0) {
|
||||||
readCallback,
|
log.info("read thread got quit signal", .{});
|
||||||
);
|
return;
|
||||||
|
|
||||||
try self.loop.run(.until_done);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readCallback(
|
const n = try os.read(self.fd, &buf);
|
||||||
ud: ?*Tty,
|
log.err("{s}", .{buf[0..n]});
|
||||||
loop: *xev.Loop,
|
}
|
||||||
c: *xev.Completion,
|
|
||||||
stream: xev.Stream,
|
|
||||||
buf: xev.ReadBuffer,
|
|
||||||
r: xev.ReadError!usize,
|
|
||||||
) xev.CallbackAction {
|
|
||||||
_ = stream; // autofix
|
|
||||||
_ = c; // autofix
|
|
||||||
_ = loop; // autofix
|
|
||||||
const tty = ud.?;
|
|
||||||
_ = tty; // autofix
|
|
||||||
const n = r catch |err| {
|
|
||||||
// Log the error and shutdown
|
|
||||||
log.err("read error: {}", .{err});
|
|
||||||
return .disarm;
|
|
||||||
};
|
|
||||||
log.info("{s}\r", .{buf.slice[0..n]});
|
|
||||||
return .rearm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// makeRaw enters the raw state for the terminal.
|
/// makeRaw enters the raw state for the terminal.
|
||||||
|
|
Loading…
Reference in a new issue