| ... | ... | @@ -193,7 +193,9 @@ pub const AtomicFile = struct { |
| 193 | 193 | self.* = undefined; |
| 194 | 194 | } |
| 195 | 195 | |
| 196 | | pub fn finish(self: *AtomicFile) !void { |
| 196 | pub const FinishError = std.os.RenameError; |
| 197 | |
| 198 | pub fn finish(self: *AtomicFile) FinishError!void { |
| 197 | 199 | assert(self.file_exists); |
| 198 | 200 | if (self.file_open) { |
| 199 | 201 | self.file.close(); |
| ... | ... | @@ -2112,17 +2114,13 @@ pub const Dir = struct { |
| 2112 | 2114 | return PrevStatus.stale; |
| 2113 | 2115 | } |
| 2114 | 2116 | |
| 2117 | pub const CopyFileError = File.OpenError || File.StatError || AtomicFile.InitError || CopyFileRawError || AtomicFile.FinishError; |
| 2118 | |
| 2115 | 2119 | /// Guaranteed to be atomic. |
| 2116 | 2120 | /// On Linux, until https://patchwork.kernel.org/patch/9636735/ is merged and readily available, |
| 2117 | 2121 | /// there is a possibility of power loss or application termination leaving temporary files present |
| 2118 | 2122 | /// in the same directory as dest_path. |
| 2119 | | pub fn copyFile( |
| 2120 | | source_dir: Dir, |
| 2121 | | source_path: []const u8, |
| 2122 | | dest_dir: Dir, |
| 2123 | | dest_path: []const u8, |
| 2124 | | options: CopyFileOptions, |
| 2125 | | ) !void { |
| 2123 | pub fn copyFile(source_dir: Dir, source_path: []const u8, dest_dir: Dir, dest_path: []const u8, options: CopyFileOptions) CopyFileError!void { |
| 2126 | 2124 | var in_file = try source_dir.openFile(source_path, .{}); |
| 2127 | 2125 | defer in_file.close(); |
| 2128 | 2126 | |
| ... | ... | @@ -2137,7 +2135,7 @@ pub const Dir = struct { |
| 2137 | 2135 | defer atomic_file.deinit(); |
| 2138 | 2136 | |
| 2139 | 2137 | try copy_file(in_file.handle, atomic_file.file.handle); |
| 2140 | | return atomic_file.finish(); |
| 2138 | try atomic_file.finish(); |
| 2141 | 2139 | } |
| 2142 | 2140 | |
| 2143 | 2141 | pub const AtomicFileOptions = struct { |
| ... | ... | @@ -2617,12 +2615,12 @@ pub fn realpathAlloc(allocator: Allocator, pathname: []const u8) ![]u8 { |
| 2617 | 2615 | return allocator.dupe(u8, try os.realpath(pathname, &buf)); |
| 2618 | 2616 | } |
| 2619 | 2617 | |
| 2620 | | const CopyFileError = error{SystemResources} || os.CopyFileRangeError || os.SendFileError; |
| 2618 | const CopyFileRawError = error{SystemResources} || os.CopyFileRangeError || os.SendFileError; |
| 2621 | 2619 | |
| 2622 | 2620 | // Transfer all the data between two file descriptors in the most efficient way. |
| 2623 | 2621 | // The copy starts at offset 0, the initial offsets are preserved. |
| 2624 | 2622 | // No metadata is transferred over. |
| 2625 | | fn copy_file(fd_in: os.fd_t, fd_out: os.fd_t) CopyFileError!void { |
| 2623 | fn copy_file(fd_in: os.fd_t, fd_out: os.fd_t) CopyFileRawError!void { |
| 2626 | 2624 | if (comptime builtin.target.isDarwin()) { |
| 2627 | 2625 | const rc = os.system.fcopyfile(fd_in, fd_out, null, os.system.COPYFILE_DATA); |
| 2628 | 2626 | switch (os.errno(rc)) { |