summaryrefslogtreecommitdiff
path: root/src/exec.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/exec.zig')
-rw-r--r--src/exec.zig22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/exec.zig b/src/exec.zig
index 0bce67d2..6e437093 100644
--- a/src/exec.zig
+++ b/src/exec.zig
@@ -341,11 +341,20 @@ pub fn spawnV9fsTty(p: *Pardes, from: usize) void {
fn spawnTtyWithMount(p: *Pardes, from: usize, v9fs: bool) ?*Pane {
if (p.panes[from] == null) return null;
+ // A directory that is not there makes no terminal: its shell could not
+ // start in it, and a dead pane would answer no run. Asked only of a host
+ // that starts shells (none, as in the core's tests, starts none).
+ const dir = p.execDir(from);
+ if (comptime hosted) if (p.host.vtable.spawn != null) if (@import("fs.zig").localPath(dir)) |local| if (!isDirectory(local)) {
+ var said: [pardes.memory.limits.host_path_cap + 48]u8 = undefined;
+ p.reportFailure(from, std.fmt.bufPrint(&said, "Tty: {s}: no such directory", .{dir}) catch "Tty: no such directory");
+ return null;
+ };
const free = p.freeSlot() orelse {
p.reportError(from, "Tty", error.NoPaneSlots);
return null;
};
- const nt = p.newShell(free, p.execDir(from)) catch |err| {
+ const nt = p.newShell(free, dir) catch |err| {
if (err == error.PathTooLong) {
p.reportFailure(from, std.fmt.comptimePrint("Tty: its directory is longer than a path may be ({d} bytes)", .{pardes.memory.limits.host_path_cap}));
return null;
@@ -360,6 +369,17 @@ fn spawnTtyWithMount(p: *Pardes, from: usize, v9fs: bool) ?*Pane {
return nt;
}
+/// Whether `path` is a directory on this host, the turn out while it asks
+/// (it may be inside a mount this editor serves).
+fn isDirectory(path: []const u8) bool {
+ var buf: [4096]u8 = undefined;
+ const z = std.fmt.bufPrintSentinel(&buf, "{s}", .{path}, 0) catch return false;
+ pardes.turn.yield();
+ defer pardes.turn.back();
+ const stat = std.Io.Dir.cwd().statFile(std.Io.Threaded.global_single_threaded.io(), z, .{}) catch return false;
+ return stat.kind == .directory;
+}
+
/// With `BootShell replace`, a doc landing in `col` closes a lone pristine
/// shell there, the boot's placeholder, and absorbVWeight hands its space to
/// the doc. With `keep`, the default, the shell stays like any other pane.