summaryrefslogtreecommitdiff
path: root/src/exec.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/exec.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/exec.zig')
-rw-r--r--src/exec.zig21
1 files changed, 14 insertions, 7 deletions
diff --git a/src/exec.zig b/src/exec.zig
index cc2d3c4f..dbda7217 100644
--- a/src/exec.zig
+++ b/src/exec.zig
@@ -292,8 +292,8 @@ fn askWrite(p: *Pardes, id: usize, serial: u32, path: []const u8) void {
/// Tty: a shell in the caller's directory, raw from the first frame,
/// stacked below the caller like Alt-n's new shell.
-pub fn spawnTty(p: *Pardes, from: usize) void {
- spawnTtyWithMount(p, from, false);
+pub fn spawnTty(p: *Pardes, from: usize) ?*Pane {
+ return spawnTtyWithMount(p, from, false);
}
pub fn spawnV9fsTty(p: *Pardes, from: usize) void {
@@ -301,13 +301,19 @@ pub fn spawnV9fsTty(p: *Pardes, from: usize) void {
return p.reportError(from, "Tty9p", error.LinuxRequired);
if (p.fs.socket_path.len == 0)
return p.reportError(from, "Tty9p", error.SessionSocketRequired);
- spawnTtyWithMount(p, from, true);
+ _ = spawnTtyWithMount(p, from, true);
}
-fn spawnTtyWithMount(p: *Pardes, from: usize, v9fs: bool) void {
- const src = p.panes[from] orelse return;
- const free = p.freeSlot() orelse return;
- const nt = p.newShell(free, Pardes.paneDir(src)) catch return;
+fn spawnTtyWithMount(p: *Pardes, from: usize, v9fs: bool) ?*Pane {
+ const src = p.panes[from] orelse return null;
+ const free = p.freeSlot() orelse {
+ p.reportFailure(from, "Tty: no pane free");
+ return null;
+ };
+ const nt = p.newShell(free, Pardes.paneDir(src)) catch |err| {
+ p.reportError(from, "Tty", err);
+ return null;
+ };
nt.greet = !v9fs;
nt.v9fs_on_spawn = v9fs;
nt.body.mode = .tty;
@@ -317,6 +323,7 @@ fn spawnTtyWithMount(p: *Pardes, from: usize, v9fs: bool) void {
layout.splitBelow(p, parent, nt);
p.active = free;
p.stillborn_joiner = nt.serial;
+ return nt;
}
/// when a doc lands in `col`, a lone pristine shell there is clutter — drop