mirror of
https://github.com/oven-sh/bun
synced 2026-02-15 13:22:07 +00:00
Fix moving files across mount points
This commit is contained in:
@@ -1112,7 +1112,7 @@ pub const Bundler = struct {
|
||||
// chmod 777
|
||||
0000010 | 0000100 | 0000001 | 0001000 | 0000040 | 0000004 | 0000002 | 0000400 | 0000200 | 0000020,
|
||||
);
|
||||
try std.os.renameatZ(tmpdir.fd, tmpname, top_dir.fd, destination);
|
||||
try C.moveFileZ(tmpdir.fd, tmpname, top_dir.fd, destination);
|
||||
// Print any errors at the end
|
||||
// try this.log.print(Output.errorWriter());
|
||||
return javascript_bundle_container;
|
||||
|
||||
28
src/c.zig
28
src/c.zig
@@ -1,4 +1,5 @@
|
||||
const std = @import("std");
|
||||
const Enviroment = @import("./env.zig");
|
||||
|
||||
pub usingnamespace switch (std.Target.current.os.tag) {
|
||||
.macos => @import("./darwin_c.zig"),
|
||||
@@ -89,3 +90,30 @@ pub fn lstat_absolute(path: [:0]const u8) StatError!Stat {
|
||||
.ctime = @as(i128, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec,
|
||||
};
|
||||
}
|
||||
|
||||
// renameatZ fails when renaming across mount points
|
||||
// we assume that this is relatively uncommon
|
||||
pub fn moveFileZ(from_dir: std.os.fd_t, filename: [*:0]const u8, to_dir: std.os.fd_t, destination: [*:0]const u8) !void {
|
||||
std.os.renameatZ(from_dir, filename, to_dir, destination) catch |err| {
|
||||
switch (err) {
|
||||
error.RenameAcrossMountPoints => {
|
||||
try moveFileZSlow(from_dir, filename, to_dir, destination);
|
||||
},
|
||||
else => {
|
||||
return err;
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// On Linux, this will be fast because sendfile() supports copying between two file descriptors on disk
|
||||
// On macOS & BSDs, this will be slow because it will attempt to copy with sendfile, fail, and then fallback to a copy loop
|
||||
pub fn moveFileZSlow(from_dir: std.os.fd_t, filename: [*:0]const u8, to_dir: std.os.fd_t, destination: [*:0]const u8) !void {
|
||||
const flags = std.os.O_RDWR;
|
||||
const in_handle = try std.os.openatZ(from_dir, filename, flags, 0777);
|
||||
defer std.os.close(in_handle);
|
||||
const out_handle = try std.os.openatZ(to_dir, filename, flags | std.os.O_CREAT, 0777);
|
||||
defer std.os.close(out_handle);
|
||||
const written = try std.os.sendfile(out_handle, in_handle, 0, 0, &[_]std.c.iovec_const{}, &[_]std.c.iovec_const{}, 0);
|
||||
try std.os.ftruncate(out_handle, written);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user