summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/gui.zig14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/gui/gui.zig b/src/gui/gui.zig
index cb3bdd97..851218bb 100644
--- a/src/gui/gui.zig
+++ b/src/gui/gui.zig
@@ -4553,10 +4553,20 @@ fn gridPostPresent(ctx: ?*anyopaque) void {
fn spawnPane(ctx: ?*anyopaque, pane: u8, cwd: []const u8) void {
const s = shellOf(ctx);
s.reap();
+ // The new shell starts before a running one goes: one that cannot
+ // start leaves the running one be (pty/ctl's exec).
+ const running = s.ptys[pane] != null;
+ 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| {
+ if (running) return s.core.restartFailed(pane, err);
+ return s.core.shellFailed(pane, err);
+ };
s.closePty(pane);
- if (s.ptys[pane] != null) return s.core.reportError(pane, "shell", error.WorkersBusy);
+ if (s.ptys[pane] != null) {
+ _ = libc.close(child.file.handle);
+ host_io.retireShell(child.pid);
+ return s.core.reportError(pane, "shell", error.WorkersBusy);
+ }
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.shellFailed(pane, 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), .fd = child.file.handle } };
s.ptys[pane] = pt;