about summary refs log tree commit diff
path: root/src/fs.zig
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/fs.zig43
1 files changed, 30 insertions, 13 deletions
diff --git a/src/fs.zig b/src/fs.zig
index 2a141d1..eb8c3e0 100644
--- a/src/fs.zig
+++ b/src/fs.zig
@@ -35,33 +35,50 @@ pub const FileSwapper = struct {
         };
     }
 
+    pub fn file(self: FileSwapper) std.fs.File {
+        return self.tmp;
+    }
+
     pub fn writer(self: FileSwapper) std.fs.File.Writer {
         return self.tmp.writer();
     }
 
-    pub fn close(self: FileSwapper) void {
-        defer self.allocator.free(self.tmp_path);
-        defer self.tmp.close();
-
-        // flush writes
-        self.tmp.sync() catch
-            @panic("sync tmp file");
-
-        // check if target path exists
+    fn target_exists(self: FileSwapper) !bool {
         var found = true;
         std.fs.cwd().access(self.target_path, .{}) catch |e| switch (e) {
             error.FileNotFound => found = false,
-            else => @panic("unable to stat target path"),
+            else => |err| return err,
         };
+        return found;
+    }
+
+    pub fn swap(self: FileSwapper) !void {
+        std.log.debug("swapping {s} -> {s}", .{ self.tmp_path, self.target_path });
+
+        // flush writes
+        self.tmp.sync() catch
+            @panic("sync tmp file");
 
         // swap file into final location
-        std.fs.rename(
+        // NOTE: the tmp fd is still valid after this
+        try std.fs.rename(
             std.fs.cwd(),
             self.tmp_path,
             std.fs.cwd(),
             self.target_path,
-        ) catch
-            @panic("rename tmp file");
+        );
+    }
+
+    pub fn close(self: FileSwapper) void {
+        var found = true;
+        std.fs.cwd().access(self.tmp_path, .{}) catch |e| switch (e) {
+            error.FileNotFound => found = false,
+            else => @panic("access tmp path"),
+        };
+        if (found) self.swap() catch @panic("failed to swap target file");
+
+        self.allocator.free(self.tmp_path);
+        self.tmp.close();
     }
 };