summaryrefslogtreecommitdiff
path: root/src/detached/server.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/detached/server.zig')
-rw-r--r--src/detached/server.zig28
1 files changed, 8 insertions, 20 deletions
diff --git a/src/detached/server.zig b/src/detached/server.zig
index b47bda1b..8fc7b96e 100644
--- a/src/detached/server.zig
+++ b/src/detached/server.zig
@@ -484,7 +484,7 @@ pub const Session = struct {
s.ninep,
) catch |err| return s.core.reportError(pane, "shell", err);
const command = if (s.core.panes[pane]) |pn| pn.command != null else false;
- s.ptys[pane] = .{ .fd = child.file.handle, .pid = child.pid, .cmd = .{ .watched = command and host_io.watchExit(child.pid) } };
+ s.ptys[pane] = .{ .fd = child.file.handle, .pid = child.pid, .cmd = .{ .watched = command and host_io.watchExit(child.pid), .fd = child.file.handle } };
setNonblock(child.file.handle);
var lbuf: [pardes.memory.limits.host_path_cap + 1]u8 = undefined;
if (host_io.shellCwd(child.pid, &lbuf)) |wd| s.core.setCwd(pane, wd);
@@ -697,11 +697,7 @@ pub const Session = struct {
// A command's pty stays open until its child has exited: closing
// it would hang up one that runs on without it.
// Its exit, if it came first, is told now its output is in.
- if (pt.cmd.watched) {
- pt.cmd.eof = true;
- s.core.update(.{ .eof = .{ .pane = pane } });
- return s.takeExits();
- }
+ if (pt.cmd.watched) return host_io.commandEof(s.core, &s.ptys, pane, s, closeWatched);
// Unwatched, a command's exit is read here, as its end.
const unwatched = if (s.core.panes[pane]) |pn| pn.command != null else false;
var status: ?u8 = null;
@@ -715,21 +711,13 @@ pub const Session = struct {
s.core.update(.{ .eof = .{ .pane = pane } });
}
- /// Each watched child that exited: reaped, the core told, and its pty
- /// closed if its end of file came first.
+ /// The command panes' exits, told once their output is in (host_io).
fn takeExits(s: *Session) void {
- while (host_io.takeExited()) |pid| for (&s.ptys) |*pt| {
- if (pt.fd < 0 or pt.pid != pid or pt.cmd.exited) continue;
- pt.cmd.exit((host_io.reapExited(pid) orelse break).status);
- pt.pid = 0; // reaped: no signal or retire may reach whoever gets it next
- break;
- };
- for (&s.ptys, 0..) |*pt, id| {
- if (pt.fd < 0 or !pt.cmd.due()) continue;
- pt.cmd.told = true;
- s.core.update(.{ .exited = .{ .pane = @intCast(id), .status = pt.cmd.status } });
- if (pt.cmd.eof) s.closePty(@intCast(id));
- }
+ host_io.takeExits(s.core, &s.ptys, s, closeWatched);
+ }
+
+ fn closeWatched(s: *Session, id: usize) void {
+ s.closePty(@intCast(id));
}
fn harvest(s: *Session) void {