diff options
Diffstat (limited to 'src/detached/server.zig')
| -rw-r--r-- | src/detached/server.zig | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/detached/server.zig b/src/detached/server.zig index a08a0342..676b5b95 100644 --- a/src/detached/server.zig +++ b/src/detached/server.zig @@ -485,9 +485,11 @@ pub const Session = struct { fn spawn(ctx: ?*anyopaque, pane: u8, cwd: []const u8) void { const s = of(ctx); if (pane >= s.ptys.len) return; // the core indexes its own panes - s.closePty(pane); s.harvest(); - if (s.ptys[pane].pid != 0) return s.core.reportError(pane, "shell", error.ShellClosing); + // 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].fd >= 0; + if (!running and s.ptys[pane].pid != 0) return s.core.reportError(pane, "shell", error.ShellClosing); for (s.retired_shells) |shell| { if (shell.pid == 0) break; } else return s.core.reportError(pane, "shell", error.ShellClosing); @@ -500,7 +502,17 @@ pub const Session = struct { s.core.screen_h, s.core.screen_w, s.ninep, - ) catch |err| return s.core.shellFailed(pane, err); + ) catch |err| { + if (running) return s.core.restartFailed(pane, err); + return s.core.shellFailed(pane, err); + }; + s.closePty(pane); + s.harvest(); + if (s.ptys[pane].pid != 0) { + _ = libc.close(child.file.handle); + host_io.retireShell(child.pid); + return s.core.reportError(pane, "shell", error.ShellClosing); + } 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), .fd = child.file.handle } }; setNonblock(child.file.handle); |
