diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-28 14:36:46 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:15 -0300 |
| commit | 0f18cc317190c2aaaf0efec4cd6da656cb1f3402 (patch) | |
| tree | fb2abbddacae3be30ea5ddcbeeca03e40cccf26c /src/host_io.zig | |
| parent | 010b123a88aa5278c499f83098c00bdbdb0093ce (diff) | |
| download | pardes-0f18cc317190c2aaaf0efec4cd6da656cb1f3402.tar.gz pardes-0f18cc317190c2aaaf0efec4cd6da656cb1f3402.zip | |
A spawn names the pane it was made for, so a pane closed and its slot retaken spawns nothing
The spawn effect carried only a slot, and the host read the command and shell
off whatever pane held the slot as it forked: a command pane closed and its
slot taken by the next one before the effects ran forked the new pane's
command twice. The effect now carries the pane's serial and is dropped when
the slot holds another; forkShell checks it again after giving up the turn
for its directory's stat, the one moment a 9P client can change the panes
under it. Every front end performs spawns with the turn, from its step.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/host_io.zig')
| -rw-r--r-- | src/host_io.zig | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/src/host_io.zig b/src/host_io.zig index 63b907ac..b167ef8a 100644 --- a/src/host_io.zig +++ b/src/host_io.zig @@ -965,6 +965,7 @@ pub fn forkShell( const native_cwd = filesystem.localPath(cwd) orelse cwd; if (std.mem.indexOfScalar(u8, native_cwd, 0) != null) return error.InvalidPath; var cwd_buf: [4096]u8 = undefined; + const serial = if (core) |c| if (c.panes[pane]) |pn| pn.serial else 0 else 0; const cwd_z: ?[:0]const u8 = if (native_cwd.len == 0) null else dir: { const path = std.fmt.bufPrintSentinel(&cwd_buf, "{s}", .{native_cwd}, 0) catch return error.NameTooLong; // A shell's directory may be inside a mount this editor serves. @@ -974,6 +975,9 @@ pub fn forkShell( if (stat.kind != .directory) return error.NotDir; break :dir path; }; + // The turn was given up for the stat: a 9P client may have closed the + // pane, and another taken its slot, whose command this is not. + if (core) |c| if ((if (c.panes[pane]) |pn| pn.serial else 0) != serial) return error.PaneGone; var master: c_int = -1; var path_buf: [std.fs.max_path_bytes]u8 = undefined; // A terminal opened on a shell of its own (`Tty fish`) runs that one. |
