╭ changed ──────╮ │src/ssh_tui.zig│ ╰───────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │192 const user_key = options.user_key orelse return error.MissingUserKey; │ │193 const term_name = environ_map.get("TERM") orelse "xterm"; │ │194 │ │195 - const initial_size = try getWinSize(); │ │195 + const initial_size = try getWinSize(io); │ │196 │ │197 const conn = try ssh.parseConnectAddress(options.tui_connect); │ │198 const address = try std.Io.net.IpAddress.parseIp4(conn.host, conn.port);│ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────╮ │208 │ │209 // self-pipe: SIGWINCH handler writes a byte, stdinProxy polls on the │ │210 // read end and converts it into a resize frame. │ │211 - var pipe_fds: [2]i32 = undefined; │ │212 - const o_flags: std.os.linux.O = .{ .NONBLOCK = true, .CLOEXEC = true }; │ │213 - if (std.posix.errno(std.os.linux.pipe2(&pipe_fds, o_flags)) != .SUCCESS) { │ │214 - return error.PipeFailed; │ │215 - } │ │211 + const pipe_fds = try std.Io.Threaded.pipe2(.{ .NONBLOCK = true, .CLOEXEC = true });│ │212 defer { │ │213 sigwinch_pipe_write = -1; │ │214 _ = std.posix.system.close(pipe_fds[1]); │ ╰────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │272 const default_width: u16 = 80; │ │273 const default_height: u16 = 24; │ │274 │ │279 -fn getWinSize() !WinSize { │ │275 +fn getWinSize(io: std.Io) !WinSize { │ │276 var ws: std.posix.winsize = undefined; │ │281 - const rc = std.os.linux.ioctl(std.posix.STDOUT_FILENO, std.posix.T.IOCGWINSZ, @intFromPtr(&ws));│ │282 - if (std.posix.errno(rc) != .SUCCESS) return error.IoctlFailed; │ │277 + const result = (try io.operate(.{ .device_io_control = .{ │ │278 + .file = std.Io.File.stdout(), │ │279 + .code = std.posix.T.IOCGWINSZ, │ │280 + .arg = &ws, │ │281 + } })).device_io_control; │ │282 + if (result < 0) return error.IoctlFailed; │ │283 return .{ │ │284 .width = if (ws.col == 0) default_width else ws.col, │ │285 .height = if (ws.row == 0) default_height else ws.row, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────╮ │309 // all collapse into one resize-frame emission. │ │310 var drain: [16]u8 = undefined; │ │311 _ = std.posix.read(ctx.pipe_read, &drain) catch {}; │ │312 - if (getWinSize()) |size| { │ │312 + if (getWinSize(ctx.io)) |size| { │ │313 writeResizeFrame(w, size.width, size.height) catch return;│ │314 w.flush() catch return; │ │315 } else |_| {} │ ╰───────────────────────────────────────────────────────────────────────────────╯