diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/9p_io.zig | 8 | ||||
| -rw-r--r-- | src/Messages.zig | 2 | ||||
| -rw-r--r-- | src/fs.zig | 4 | ||||
| -rw-r--r-- | src/ninep/ctl.zig | 10 |
4 files changed, 20 insertions, 4 deletions
diff --git a/src/9p_io.zig b/src/9p_io.zig index 7f490f81..6f05e3ab 100644 --- a/src/9p_io.zig +++ b/src/9p_io.zig @@ -312,11 +312,14 @@ pub const Listener = struct { if (restoring) l.restore_writer.store(true, .release); defer if (restoring) l.restore_writer.store(false, .release); core.fs.late_failure_len = 0; + // What fails while this waits is this write's err, never a msg too. + core.fs.write_waits = true; if (core.effects_len != 0) pardes.turn.awaitSettled(epoch); if (core.fs.lsp_answer_at) |n| { core.fs.lsp_answer_at = null; pardes.turn.awaitLsp(n); } + core.fs.write_waits = false; // ponytail: one slot, so a failure of another client's effects that // settle in the same wait is told to this write too. if (l.core == core and core.fs.late_failure_len != 0) { @@ -327,9 +330,8 @@ pub const Listener = struct { pardes.ctlfs.E.NOENT else if (std.mem.indexOf(u8, late, "no space") != null) pardes.ctlfs.E.NOSPC else pardes.ctlfs.E.IO; const failed = pardes.ctlfs.failText(req.tag, errno, late); - // Its err record says it (the path in it); the msg the failure - // was also said as goes, as a builtin's failing a write does. - pardes.ctlfs.events.dropMessage(core, core.fs.late_failure[0..core.fs.late_failure_len]); + // Its err record says it (the path in it), the one record: it + // was said with no msg while this waited (fs.write_waits). pardes.ctlfs.events.noteError(core, req, failed); return conn.reply(&failed, ""); } diff --git a/src/Messages.zig b/src/Messages.zig index aebaff0c..7342f726 100644 --- a/src/Messages.zig +++ b/src/Messages.zig @@ -505,7 +505,7 @@ pub fn reportFailure(p: *Pardes, id: usize, text: []const u8) void { p.fs.failures +%= 1; // A builtin a ctl write runs: its first error is also the write's, cut // between words. - const failing_write = p.fs.no_prompt or p.fs.capturing; + const failing_write = p.fs.no_prompt or p.fs.capturing or p.fs.write_waits; if (failing_write and p.fs.failure_len == 0) { const kept = if (text.len > p.fs.failure.len) clip(text, p.fs.failure.len - 3) else text; @memcpy(p.fs.failure[0..kept.len], kept); @@ -1330,6 +1330,10 @@ pub const Namespace = struct { /// its header), 0 when unknown: a write shorter than it is the whole of /// what its client wrote, one that fills it may be cut and go on. write_room: u32 = 0, + /// A 9P write waits on what the editor performs for it (a Save's disk + /// write, a shell, a language server): a failure said meanwhile is that + /// write's err, so it posts no msg (Messages.reportFailure). + write_waits: bool = false, /// Writes one open made in a row into one place of a pane's body (an /// append to `body`, an insert at `data`'s address), held and put in /// as one edit when anything else comes (ninep/pane.zig flushBatch): a diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig index 397f3339..63e7e76a 100644 --- a/src/ninep/ctl.zig +++ b/src/ninep/ctl.zig @@ -2234,6 +2234,16 @@ test "a buffer whose file was deleted on disk is dirty, and Del asks first" { try testing.expect(p.paneBySerial(serial) == null); } +test "a failure said while a 9P write waits on it posts no msg, only the write's err" { + const p = try withFile(testing.allocator, "x\n"); + defer p.deinit(); + p.fs.write_waits = true; + p.saveFailed(@intCast(p.active), "/nowhere/zz.txt", error.FileNotFound); + p.fs.write_waits = false; + try testing.expect(!th.logHas(p, "msg ")); + try testing.expect(p.fs.late_failure_len > 0); +} + test "every EINVAL a write gets says why, in its err record too; DEL is a control character in a line" { const p = try withFile(testing.allocator, "x\n"); defer p.deinit(); |
