diff options
Diffstat (limited to 'src/exec.zig')
| -rw-r--r-- | src/exec.zig | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/exec.zig b/src/exec.zig index 47484105..ca48bed1 100644 --- a/src/exec.zig +++ b/src/exec.zig @@ -766,10 +766,13 @@ fn runCommand(p: *Pardes, from: usize, line: []const u8) ?usize { // would hang that job up. // From a column's tag, only a finished pane in that column is reused, // as the new one goes in that column (placeNew). - const reuse: ?usize = if (!p.exec_header and p.exec_column == null and src != null and src.?.command != null and src.?.command_done and !src.?.command_pty) from else for (p.panes, 0..) |slot, i| { + // Nor one leased: an open that was answered its serial and is still + // open reads that pane's output, which another client's command must + // not replace; a new pane runs it instead. + const reuse: ?usize = if (!p.exec_header and p.exec_column == null and src != null and src.?.command != null and src.?.command_done and !src.?.command_pty and !leased(p, src.?.serial)) from else for (p.panes, 0..) |slot, i| { const other = slot orelse continue; if (p.exec_column) |c| if (if (layout.findPane(p, i)) |f| f.col != c else true) continue; - if (other.command != null and other.command_done and !other.command_pty and std.mem.eql(u8, other.cwdSlice(), dir)) break i; + if (other.command != null and other.command_done and !other.command_pty and std.mem.eql(u8, other.cwdSlice(), dir) and !leased(p, other.serial)) break i; } else null; if (reuse) |id| { const pane = p.panes[id].?; @@ -812,6 +815,15 @@ fn runCommand(p: *Pardes, from: usize, line: []const u8) ?usize { return free; } +/// Whether an open of a look or exec file holds `serial` from its own write +/// (tree.Open.results): its client is reading that pane. +fn leased(p: *const Pardes, serial: u32) bool { + for (p.fs.opens) |o| if (o.node != 0 and o.results.wrote) { + if (std.mem.indexOfScalar(u32, o.results.list[0..o.results.len], serial) != null) return true; + }; + return false; +} + /// The serial a command's `$winid` names: the pane it was run from, none /// (0) from a column's or the workspace's tag. fn winid(p: *const Pardes, src: ?*Pane) u32 { |
