summaryrefslogtreecommitdiff
path: root/src/ninep/pty.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 11:26:42 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:16 -0300
commit0e6501ce210481c095e6f70a27e7f125f7af3761 (patch)
tree0abf4b55e8eb4f836a3ad10963cbefd94efb8599 /src/ninep/pty.zig
parent1ac8fbeedaf7cba881a7423b92ead1f739b8ac21 (diff)
downloadpardes-0e6501ce210481c095e6f70a27e7f125f7af3761.tar.gz
pardes-0e6501ce210481c095e6f70a27e7f125f7af3761.zip
A pty/ctl exec that cannot start its shell keeps the one running
Each host closed the running shell before it forked the new one, so an exec whose shell failed left the pane with none and later runs answered error shell gone. A shell not there is now refused up front, and every host starts the new shell first, replacing the old only once the close-on-exec pipe says it ran; a failure there is only said (restartFailed). Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/pty.zig')
-rw-r--r--src/ninep/pty.zig8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/ninep/pty.zig b/src/ninep/pty.zig
index aa0f499a..bf5f432c 100644
--- a/src/ninep/pty.zig
+++ b/src/ninep/pty.zig
@@ -67,6 +67,14 @@ pub fn writeCtl(p: *Pardes, req: Req, id: usize) Reply {
const dir = pane.cwdSlice();
return tree.failText(req.tag, E.NOENT, std.fmt.bufPrint(&p.fs.ename, "exec: {s}: no such directory", .{dir[0..@min(dir.len, 256)]}) catch "exec: no such directory");
};
+ // Nor is a shell that is not there, or a script whose
+ // interpreter is not: refused, and the running shell kept.
+ if (comptime pardes.hosted) if (!apply and std.mem.eql(u8, line, "exec")) if (p.panes[id]) |pane| {
+ const bin = pane.shell orelse p.shellBin();
+ var why: [320]u8 = undefined;
+ if (@import("../host_io.zig").Shell.refusal(bin[0..@min(bin.len, 200)], &why)) |refused|
+ return tree.failText(req.tag, E.NOENT, std.fmt.bufPrint(&p.fs.ename, "exec: {s}", .{refused}) catch "exec: no such shell");
+ };
if (!verb(p, id, line, apply)) return tree.failText(req.tag, E.INVAL, if (outOfRange(line)) e_winsize_range else e_bad_pty_ctl);
}
}