summaryrefslogtreecommitdiff
path: root/src/exec.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/exec.zig')
-rw-r--r--src/exec.zig23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/exec.zig b/src/exec.zig
index ca48bed1..080d0aea 100644
--- a/src/exec.zig
+++ b/src/exec.zig
@@ -413,9 +413,28 @@ fn spawnTtyWithMount(p: *Pardes, from: usize, v9fs: bool) ?*Pane {
nt.v9fs_on_spawn = v9fs;
nt.body.mode = .tty;
placeNew(p, from, from, free, .shell);
+ if (refusedPlacement(p, free)) {
+ p.reportError(from, "Tty", error.NoPaneRoom);
+ return null;
+ }
return nt;
}
+/// A pane placeNew found no room for: taken back now, before anything is
+/// logged of it or answered with its serial (it was never announced), so
+/// no `new`/`del` pair and no serial a script was told of is left behind.
+fn refusedPlacement(p: *Pardes, id: usize) bool {
+ if (!p.unplaced.isSet(id)) return false;
+ p.unplaced.unset(id);
+ p.removePane(id, null) catch {};
+ // As sync does for a refused pane: none it squeezed stays under its
+ // minimum.
+ for (0..p.ncol) |c| if (!layout.columnAtMinimums(p, c)) {
+ _ = layout.shareColumn(p, c);
+ };
+ return true;
+}
+
/// Whether a shell would be started in `dir` and `dir` is not there: asked
/// only of a host that starts shells, and only of a local path.
pub fn missingDir(p: *Pardes, dir: []const u8) bool {
@@ -811,6 +830,10 @@ fn runCommand(p: *Pardes, from: usize, line: []const u8) ?usize {
pane.command_from = winid(p, src);
echoCommand(p, pane, line);
placeNew(p, from, from, free, .command);
+ if (refusedPlacement(p, free)) {
+ p.reportError(from, "exec", error.NoPaneRoom);
+ return null;
+ }
noteRun(p, pane, "run", line);
return free;
}