summaryrefslogtreecommitdiff
path: root/src/gui/gui.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/gui.zig')
-rw-r--r--src/gui/gui.zig33
1 files changed, 11 insertions, 22 deletions
diff --git a/src/gui/gui.zig b/src/gui/gui.zig
index 46bd5ffc..0cfe80f5 100644
--- a/src/gui/gui.zig
+++ b/src/gui/gui.zig
@@ -3878,29 +3878,20 @@ const Shell = struct {
break :vt v;
};
- /// 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: *Shell) void {
- while (host_io.takeExited()) |pid| for (s.ptys) |*slot| {
- const pt = if (slot.*) |*pt| pt else continue;
- if (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..) |*slot, id| {
- const pt = if (slot.*) |*pt| pt else continue;
- if (!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));
- s.saw_event = true;
- }
+ host_io.takeExits(s.core, s.ptys, s, closeWatched);
+ }
+
+ fn closeWatched(s: *Shell, id: usize) void {
+ s.closePty(@intCast(id));
+ s.saw_event = true;
}
fn drainQueue(s: *Shell) void {
s.reconcilePtys();
- s.takeExits();
+ // After this batch's output, which an exit is told behind.
+ defer s.takeExits();
var msgs = s.queue.take();
var check_files = false;
for (msgs.slice()) |m| switch (m) {
@@ -3928,9 +3919,7 @@ const Shell = struct {
// 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 = e.pane } });
- s.takeExits();
+ host_io.commandEof(s.core, s.ptys, e.pane, s, closeWatched);
break :eof;
}
// Unwatched, a command's exit is read here, as its end.
@@ -4218,7 +4207,7 @@ fn spawnPane(ctx: ?*anyopaque, pane: u8, cwd: []const u8) void {
s.gens[pane] +%= 1;
const child = host_io.forkShell(s.core, pane, s.prompt_rcs, s.core.shellBin(), cwd, s.core.screen_h, s.core.screen_w, s.fs) catch |err| return s.core.reportError(pane, "shell", err);
const command = s.core.panes[pane].?.command != null;
- const pt: Pty = .{ .fd = child.file.handle, .pid = child.pid, .serial = s.core.panes[pane].?.serial, .cmd = .{ .watched = command and host_io.watchExit(child.pid) } };
+ const pt: Pty = .{ .fd = child.file.handle, .pid = child.pid, .serial = s.core.panes[pane].?.serial, .cmd = .{ .watched = command and host_io.watchExit(child.pid), .fd = child.file.handle } };
s.ptys[pane] = pt;
var lbuf: [pardes.memory.limits.host_path_cap + 1]u8 = undefined;
if (host_io.shellCwd(pt.pid, &lbuf)) |wd| s.core.setCwd(pane, wd);