summaryrefslogtreecommitdiff
path: root/src/host_io.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/host_io.zig')
-rw-r--r--src/host_io.zig5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/host_io.zig b/src/host_io.zig
index 85ba94f4..072f3100 100644
--- a/src/host_io.zig
+++ b/src/host_io.zig
@@ -872,6 +872,8 @@ pub const Shell = struct {
@memcpy(buf[0..bin.len], bin);
buf[bin.len] = 0;
if (isDirectory(@ptrCast(&buf))) return std.fmt.bufPrint(said, "not a shell: {s} is a directory", .{bin}) catch "not a shell: a directory";
+ // There, but no program: said so, not "not found".
+ if (libc.access(@ptrCast(&buf), 0) == 0) return std.fmt.bufPrint(said, "not a shell: {s} is not executable", .{bin}) catch "not a shell: not executable";
}
// "not found": the words a mount reads as ENOENT.
return std.fmt.bufPrint(said, "no shell \"{s}\", not found (a name on the usual paths, or a path to one)", .{bin}) catch "no such shell";
@@ -912,6 +914,9 @@ pub const Shell = struct {
try std.testing.expectEqualStrings("interpreter /no/such/interp not found", refusal(try std.fmt.bufPrint(&path, "{s}/bad", .{dir}), &said).?);
try std.testing.expect(refusal(try std.fmt.bufPrint(&path, "{s}/good", .{dir}), &said) == null);
try std.testing.expect(std.mem.startsWith(u8, refusal(try std.fmt.bufPrint(&path, "{s}/none", .{dir}), &said).?, "no shell "));
+ try tmp.dir.writeFile(std.testing.io, .{ .sub_path = "plain", .data = "echo\n" });
+ const plain = try std.fmt.bufPrint(&path, "{s}/plain", .{dir});
+ try std.testing.expect(std.mem.endsWith(u8, refusal(plain, &said).?, "plain is not executable"));
}
fn fallback(buf: *[std.fs.max_path_bytes]u8) [*:0]const u8 {