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 posix = std.posix;
9
10pty: std.fs.File,
11tty: std.fs.File,
12
13/// opens a new tty/pty pair
14pub fn init() !Pty {
15 switch (builtin.os.tag) {
16 .linux => return openPtyLinux(),
17 else => @compileError("unsupported os"),
18 }
19}
20
21/// closes the tty and pty
22pub fn deinit(self: Pty) void {
23 self.pty.close();
24 self.tty.close();
25}
26
27/// sets the size of the pty
28pub fn setSize(self: Pty, ws: Winsize) !void {
29 const _ws: posix.winsize = .{
30 .row = @truncate(ws.rows),
31 .col = @truncate(ws.cols),
32 .xpixel = @truncate(ws.x_pixel),
33 .ypixel = @truncate(ws.y_pixel),
34 };
35 if (posix.system.ioctl(self.pty.handle, posix.T.IOCSWINSZ, @intFromPtr(&_ws)) != 0)
36 return error.SetWinsizeError;
37}
38
39fn openPtyLinux() !Pty {
40 const p = try posix.open("/dev/ptmx", .{ .ACCMODE = .RDWR, .NOCTTY = true }, 0);
41 errdefer posix.close(p);
42
43 // unlockpt
44 var n: c_uint = 0;
45 if (posix.system.ioctl(p, posix.T.IOCSPTLCK, @intFromPtr(&n)) != 0) return error.IoctlError;
46
47 // ptsname
48 if (posix.system.ioctl(p, posix.T.IOCGPTN, @intFromPtr(&n)) != 0) return error.IoctlError;
49 var buf: [16]u8 = undefined;
50 const sname = try std.fmt.bufPrint(&buf, "/dev/pts/{d}", .{n});
51 std.log.debug("pts: {s}", .{sname});
52
53 const t = try posix.open(sname, .{ .ACCMODE = .RDWR, .NOCTTY = true }, 0);
54
55 return .{
56 .pty = .{ .handle = p },
57 .tty = .{ .handle = t },
58 };
59}