diff options
Diffstat (limited to 'src/host_io.zig')
| -rw-r--r-- | src/host_io.zig | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/src/host_io.zig b/src/host_io.zig index 0f6fd87e..68d35a9c 100644 --- a/src/host_io.zig +++ b/src/host_io.zig @@ -743,8 +743,13 @@ pub const Shell = struct { return .{ .path = path, .argv = .{ path, marks[0], marks[1], null } }; } - fn find(bin: []const u8, buf: *[std.fs.max_path_bytes]u8) ?[*:0]const u8 { + /// A shell by its path or its name in the usual directories, or null. + /// A path may be under a mount this editor serves: the turn goes out + /// with the lookups (pardes.Turn.yield). + pub fn find(bin: []const u8, buf: *[std.fs.max_path_bytes]u8) ?[*:0]const u8 { if (bin.len == 0 or bin.len + 1 > buf.len) return null; + pardes.turn.yield(); + defer pardes.turn.back(); if (std.mem.indexOfScalar(u8, bin, '/') != null) { @memcpy(buf[0..bin.len], bin); buf[bin.len] = 0; @@ -975,14 +980,22 @@ 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. - const own = if (core) |c| if (c.panes[pane]) |pn| pn.shell else null else null; + // A terminal opened on a shell of its own (`Tty fish`) runs that one, + // copied: looking it up gives the turn up, and the pane may go. + var own_buf: [256]u8 = undefined; + var own: ?[]const u8 = null; + if (core) |c| if (c.panes[pane]) |pn| if (pn.shell) |name| { + const n = @min(name.len, own_buf.len); + @memcpy(own_buf[0..n], name[0..n]); + own = own_buf[0..n]; + }; var spawn = Shell.resolve(own orelse bin, &path_buf, prompt_rcs); + // The turn was given up for the stat and the lookup: 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; // A command pane's child is the shell running its one line, which has // no prompt to mark (exec.zig runCommand). const one_line = if (core) |c| if (c.panes[pane]) |pn| pn.command else null else null; |
