summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/builtins.zig9
-rw-r--r--src/ninep/ctl.zig20
2 files changed, 25 insertions, 4 deletions
diff --git a/src/builtins.zig b/src/builtins.zig
index 59fc140d..095eadbd 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -705,7 +705,14 @@ pub const Unmount = struct {
var args = std.mem.tokenizeAny(u8, c.arg orelse "", " \t");
const name = args.next() orelse return c.p.reportError(c.id, "Unmount name", error.MissingArgument);
if (args.next() != null) return c.p.reportError(c.id, "Unmount name", error.TooManyArguments);
- pardes.filesystem.unmount(c.p, name) catch |err| return c.p.reportError(c.id, "Unmount", err);
+ pardes.filesystem.unmount(c.p, name) catch |err| {
+ // "no such": the words 9ns reads as ENOENT.
+ if (err == error.NotMounted) {
+ var said: [96]u8 = undefined;
+ return c.p.reportFailure(c.id, std.fmt.bufPrint(&said, "Unmount: no such mount {s}", .{name[0..@min(name.len, 32)]}) catch "Unmount: no such mount");
+ }
+ return c.p.reportError(c.id, "Unmount", err);
+ };
}
};
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index 330b9cb7..0ec5dc2a 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -239,7 +239,13 @@ pub fn captured(p: *Pardes, req: Req, id: usize, exec: bool, text: []const u8, i
p.fs.results_len = 0;
const failure = p.fs.failure[0..p.fs.failure_len];
// A slot or a place refused keeps its errno words (no space: ENOSPC).
- return tree.failText(req.tag, E.IO, std.fmt.bufPrint(&p.fs.ename, "{s}", .{failure}) catch failure);
+ return tree.failText(req.tag, failureErrno(failure), std.fmt.bufPrint(&p.fs.ename, "{s}", .{failure}) catch failure);
+}
+
+/// The errno a builtin's failure answers with: ENOENT for what is not
+/// there (`no such`, the words 9ns reads as ENOENT too), else EIO.
+fn failureErrno(failure: []const u8) u16 {
+ return if (std.mem.indexOf(u8, failure, "no such") != null) E.NOENT else E.IO;
}
pub fn resultsLen(p: *Pardes) u64 {
@@ -444,7 +450,7 @@ pub fn runBuiltin(p: *Pardes, req: Req, id: usize, line: []const u8) ?Reply {
// line, a program, is not quoted after it.
const edit = std.mem.startsWith(u8, line, "Edit ") or std.mem.eql(u8, line, "Edit");
const refusal = if (edit) tree.failText(req.tag, E.IO, p.fs.failure[0..p.fs.failure_len]) else refuse(p, req, p.fs.failure[0..p.fs.failure_len], line);
- return .{ .tag = req.tag, .status = .err, .errno = E.IO, .ename = refusal.ename };
+ return .{ .tag = req.tag, .status = .err, .errno = failureErrno(p.fs.failure[0..p.fs.failure_len]), .ename = refusal.ename };
}
const e_prompt = "control message needs its argument";
@@ -1793,7 +1799,7 @@ test "Tty in a directory that is not there fails and makes no pane; a shell that
var count: usize = 0;
for (p.panes) |slot| count += @intFromBool(slot != null);
const refused = wr(p, Node.of(serial, .ctl), "Tty\n");
- try testing.expectEqual(E.IO, refused.errno());
+ try testing.expectEqual(E.NOENT, refused.errno());
try testing.expectStringStartsWith(refused.reply.ename, "Tty: /tmp/pardes-no-such-dir-zz: no such directory");
var after: usize = 0;
for (p.panes) |slot| after += @intFromBool(slot != null);
@@ -1842,6 +1848,14 @@ test "Grep with no hit says grep: no match and opens nothing, a missing pane dir
try testing.expectEqual(count, after);
}
+test "Unmount of a name not mounted says no such mount, which a mount reads as ENOENT" {
+ const p = try withFile(testing.allocator, "x\n");
+ defer p.deinit();
+ const refused = wr(p, @intFromEnum(tree.TopFile.ctl), "Unmount nothere\n");
+ try testing.expectEqual(E.NOENT, refused.errno());
+ try testing.expectStringStartsWith(refused.reply.ename, "Unmount: no such mount nothere");
+}
+
test "size is monotonic: growing is never refused, and a size once taken is taken again" {
const p = try Pardes.init(testing.allocator, .{ .tty_only = true, .cols = 160, .rows = 60 });
defer p.deinit();