╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ ssh_tui.zig ──────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
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, 286 }; 287 } 288 289 const StdinThreadCtx = struct { 290 io: std.Io, 291 stream: std.Io.net.Stream, 292 pipe_read: std.posix.fd_t, 293 }; 294 295 fn stdinProxy(ctx: StdinThreadCtx) void { 296 var send_buf: [4096]u8 = undefined; 297 var stream_writer = ctx.stream.writer(ctx.io, &send_buf); 298 const w = &stream_writer.interface; 299 300 while (true) { 301 var fds = [_]std.posix.pollfd{ 302 .{ .fd = std.posix.STDIN_FILENO, .events = std.posix.POLL.IN, .revents = 0 }, 303 .{ .fd = ctx.pipe_read, .events = std.posix.POLL.IN, .revents = 0 }, 304 }; 305 _ = std.posix.poll(&fds, -1) catch return; 306 307 if (fds[1].revents & std.posix.POLL.IN != 0) { 308 // drain whatever's in the pipe — multiple coalesced SIGWINCHes 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(ctx.io)) |size| { 313 writeResizeFrame(w, size.width, size.height) catch return; 314 w.flush() catch return; 315 } else |_| {} 316 } 317 if (fds[0].revents & std.posix.POLL.IN != 0) { 318 var buf: [4096]u8 = undefined; 319 const n = std.posix.read(std.posix.STDIN_FILENO, &buf) catch return; 320 if (n == 0) { 321 writeCloseFrame(w) catch {}; 322 w.flush() catch {}; 323 ctx.stream.shutdown(ctx.io, .send) catch {}; 324 return; 325 } 326 writeDataFrame(w, buf[0..n]) catch return; 327 w.flush() catch return; 328 } 329 } 330 } 331