this repo has no description
1//! A PTY pair
2const Pty = @This();
3
4const std = @import("std");
5const builtin = @import("builtin");
6const Winsize = @import("../../main.zig").Winsize;
7
8const linux = std.os.linux;
9const posix = std.posix;
10
11pty: std.Io.File,
12tty: std.Io.File,
13
14/// opens a new tty/pty pair
15pub fn init(io: std.Io) !Pty {
16 switch (builtin.os.tag) {
17 .linux => return openPtyLinux(io),
18 else => @compileError("unsupported os"),
19 }
20}
21
22/// closes the tty and pty
23pub fn deinit(self: Pty, io: std.Io) void {
24 self.pty.close(io);
25 self.tty.close(io);
26}
27
28/// sets the size of the pty
29pub fn setSize(self: Pty, ws: Winsize) !void {
30 const _ws: posix.winsize = .{
31 .row = @truncate(ws.rows),
32 .col = @truncate(ws.cols),
33 .xpixel = @truncate(ws.x_pixel),
34 .ypixel = @truncate(ws.y_pixel),
35 };
36 if (posix.system.ioctl(self.pty.handle, posix.T.IOCSWINSZ, @intFromPtr(&_ws)) != 0)
37 return error.SetWinsizeError;
38}
39
40fn openPtyLinux(io: std.Io) !Pty {
41 const pty = try std.Io.Dir.openFileAbsolute(io, "/dev/ptmx", .{
42 .mode = .read_write,
43 .allow_ctty = false,
44 });
45 errdefer pty.close(io);
46
47 // unlockpt
48 var n: c_uint = 0;
49 if (posix.system.ioctl(pty.handle, posix.T.IOCSPTLCK, @intFromPtr(&n)) != 0) return error.IoctlError;
50
51 // ptsname
52 if (posix.system.ioctl(pty.handle, posix.T.IOCGPTN, @intFromPtr(&n)) != 0) return error.IoctlError;
53 var buf: [16]u8 = undefined;
54 const sname = try std.fmt.bufPrint(&buf, "/dev/pts/{d}", .{n});
55 std.log.debug("pts: {s}", .{sname});
56
57 const tty = try std.Io.Dir.openFileAbsolute(io, sname, .{
58 .mode = .read_write,
59 .allow_ctty = false,
60 });
61
62 return .{
63 .pty = pty,
64 .tty = tty,
65 };
66}