diff options
Diffstat (limited to 'src/host.zig')
| -rw-r--r-- | src/host.zig | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/src/host.zig b/src/host.zig index d5f5c983..2c6bd208 100644 --- a/src/host.zig +++ b/src/host.zig @@ -116,6 +116,17 @@ pub const Host = struct { /// `pane` travels with the bytes only so a host that posts a "saved" /// message row can name the right pane; the core already resolved the /// path and the content, so save_file and save_text both land here. + /// + /// A HOST THAT COULD NOT WRITE MUST CALL `Pardes.saveFailed`, and the + /// reason it is a call rather than a return value is the rule twenty + /// lines below: a `push_` reaches every host in a fan-out, so there is + /// no single answer to give back. The core marks the pane saved + /// optimistically around this call and `saveFailed` takes it back, so a + /// write that could not happen — a read-only file, a directory removed + /// under the pane, a full disk — leaves the ` *` in the tag where it + /// was. Until that existed the pane came clean on a save that never + /// happened, and `Del` makes no dirty check: the edits were one click + /// from gone with the screen saying they were safe. push_write_file: ?*const fn (ctx: ?*anyopaque, pane: u8, path: []const u8, bytes: []const u8) void = null, /// The session dump. Separate because the host also chooses WHERE it /// goes (dump.outPath is libc-bound; the freestanding core cannot). @@ -188,21 +199,26 @@ pub const Fallback = struct { f.link.deinit(f.gpa); } - pub fn writeFile(f: *Fallback, path: []const u8, bytes: []const u8) void { - const copy = f.gpa.dupe(u8, bytes) catch return; + /// True when the bytes are in the map. The core turns a false into the same + /// `saveFailed` a real host reports, so a virtual filesystem that could not + /// allocate does not leave a pane looking saved either. + pub fn writeFile(f: *Fallback, path: []const u8, bytes: []const u8) bool { + const copy = f.gpa.dupe(u8, bytes) catch return false; if (f.files.getEntry(path)) |e| { f.gpa.free(e.value_ptr.*); e.value_ptr.* = copy; - return; + return true; } const key = f.gpa.dupe(u8, path) catch { f.gpa.free(copy); - return; + return false; }; f.files.put(f.gpa, key, copy) catch { f.gpa.free(key); f.gpa.free(copy); + return false; }; + return true; } /// What this path holds now: the session's own write, else the embedded |
