summaryrefslogtreecommitdiff
path: root/src/ninep/ctl.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/ninep/ctl.zig')
-rw-r--r--src/ninep/ctl.zig28
1 files changed, 21 insertions, 7 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index 8cf4f0a8..76cba9d5 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -760,11 +760,17 @@ pub fn writePane(p: *Pardes, req: Req, pane: *Pane) Reply {
const r = refuse(p, req, said, line);
return .{ .tag = req.tag, .status = .err, .errno = E.IO, .ename = r.ename };
}
- const errno = get(p, pane);
- // Naming the path, in words 9ns reads as the errno.
+ var failed: anyerror = error.Unexpected;
+ const errno = get(p, pane, &failed);
+ // Naming the path, in words 9ns reads as the errno; a peer
+ // out of reach as a look or a Save says it.
if (errno != 0) {
const path = if (pane_files.fileOf(pane)) |f| f.path else "";
- return tree.failText(req.tag, errno, std.fmt.bufPrint(&p.fs.ename, "get: {s}: {s}", .{ path[0..@min(path.len, 256)], if (errno == E.NOENT) "no such file" else "cannot be read" }) catch "get: no such file");
+ var why_buf: [48]u8 = undefined;
+ const why = if (pardes.Messages.dialReason(failed)) |r|
+ std.fmt.bufPrint(&why_buf, "dial failed: {s}", .{r}) catch "dial failed"
+ else if (errno == E.NOENT) "no such file" else "cannot be read";
+ return tree.failText(req.tag, errno, std.fmt.bufPrint(&p.fs.ename, "get: {s}: {s}", .{ path[0..@min(path.len, 256)], why }) catch "get: no such file");
}
} else if (std.mem.eql(u8, line, "lock")) {
if (mine == null) return tree.failText(req.tag, E.INVAL, tree.e_bad_ctl);
@@ -838,12 +844,15 @@ fn getRefused(p: *Pardes, pane: *Pane) ?[]const u8 {
return said;
}
-fn get(p: *Pardes, pane: *Pane) u16 {
+fn get(p: *Pardes, pane: *Pane, failed: *anyerror) u16 {
const f = pane_files.fileOf(pane) orelse return 0;
if (!panes.Output.fileTraits(f.output).saves) return 0;
- const bytes = fs.read(p, f.path) catch |err| return switch (err) {
- error.FileNotFound => E.NOENT,
- else => E.IO,
+ const bytes = fs.read(p, f.path) catch |err| {
+ failed.* = err;
+ return switch (err) {
+ error.FileNotFound => E.NOENT,
+ else => E.IO,
+ };
};
// Throwing unsaved edits away for it is a reload the log hears of, as a
// clean one from the watch is.
@@ -1736,6 +1745,11 @@ test "Mount dials its peer and fails, mounting nothing, when none answers; a loo
try testing.expectEqual(E.IO, refused.errno());
try testing.expectEqualStrings("Mount dead " ++ dead ++ ": dial failed: no answer \"Mount dead " ++ dead ++ "\"", refused.reply.ename);
try testing.expectEqual(@as(usize, 0), p.fs.mounts.items.len);
+ // A pane of a peer gone since: get says so too.
+ try p.fs.mounts.append(p.gpa, .{ .name = try p.gpa.dupe(u8, "away"), .dial = try p.gpa.dupe(u8, dead) });
+ _ = wr(p, Node.of(serialOf(p), .name), "/n/away/f.txt\n");
+ const got = wr(p, Node.of(serialOf(p), .ctl), "get\n");
+ try testing.expectEqualStrings("get: /n/away/f.txt: dial failed: no answer", got.reply.ename);
// Mounted when it answered, gone since: a look through it says so.
try p.fs.mounts.append(p.gpa, .{ .name = try p.gpa.dupe(u8, "gone"), .dial = try p.gpa.dupe(u8, dead) });
const looked = wr(p, @intFromEnum(tree.TopFile.look), "/n/gone/f.txt\n");