summaryrefslogtreecommitdiff
path: root/src/builtins.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 15:49:45 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commit2868137e34c973a47cbf667a431e885ca23cd9a2 (patch)
tree2756597f564038f22f61d77f00598a6c996fcd05 /src/builtins.zig
parent5570377c4997a5abe9f433bc15c927bcde237dc1 (diff)
downloadpardes-2868137e34c973a47cbf667a431e885ca23cd9a2.tar.gz
pardes-2868137e34c973a47cbf667a431e885ca23cd9a2.zip
Tty with a shell that is not there says so, and never sets the caller's shell
Tty /nonexistent or Tty fsh started the host's fallback shell without a word, and when spawnTty made no pane, the argument became the calling pane's shell. Tty now looks the shell up first and fails 'Tty: no shell "fsh"' when it is neither a name on the usual paths nor a path to one; spawnTty answers the pane it made, the one given the shell, and says why when it made none. The lookup (host_io Shell.find) gives the turn up around its access() calls, since a typed path may be under a mount this editor serves, and forkShell copies the pane's shell before looking it up and checks the pane is still its own after. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/builtins.zig')
-rw-r--r--src/builtins.zig17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/builtins.zig b/src/builtins.zig
index fbab925c..751d4026 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -874,11 +874,18 @@ pub const Tty = struct {
pub const takes_arg = true;
pub const plus_arg = true;
pub fn run(c: Ctx) void {
- exec.spawnTty(c.p, c.id);
- const arg = c.arg orelse return;
- const pane = c.p.panes[c.p.active] orelse return;
- if (!pane.isTerminal() or pane.shell != null) return;
- pane.shell = c.p.gpa.dupe(u8, arg) catch return;
+ const arg = std.mem.trim(u8, c.arg orelse "", " \t");
+ // A shell that is not there is said, where the host would quietly
+ // start its fallback in its place.
+ if (arg.len > 0) {
+ var buf: [std.fs.max_path_bytes]u8 = undefined;
+ if (comptime pardes.hosted) if (@import("host_io.zig").Shell.find(arg, &buf) == null) {
+ var said: [320]u8 = undefined;
+ return c.p.reportFailure(c.id, std.fmt.bufPrint(&said, "Tty: no shell \"{s}\" (a name on the usual paths, or a path to one)", .{arg[0..@min(arg.len, 200)]}) catch "Tty: no such shell");
+ };
+ }
+ const pane = exec.spawnTty(c.p, c.id) orelse return;
+ if (arg.len > 0) pane.shell = c.p.gpa.dupe(u8, arg) catch null;
}
};