aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-08-09 05:46:18 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-08-09 05:48:20 -0700
commit16f24086f8f3cae2ac16b70d67a039ea363aed1d (patch)
treed6d1dea37f5b798c471790c7e81d6fa0bc7ea5e2 /src/bun.js
parentf4ab46a8bd46e253b3ca5de068df9766f85d0d62 (diff)
downloadbun-16f24086f8f3cae2ac16b70d67a039ea363aed1d.tar.gz
bun-16f24086f8f3cae2ac16b70d67a039ea363aed1d.tar.zst
bun-16f24086f8f3cae2ac16b70d67a039ea363aed1d.zip
[node compat] Improve fs.copyFileSync performance on macOS
Diffstat (limited to 'src/bun.js')
m---------src/bun.js/WebKit0
-rw-r--r--src/bun.js/node/node_fs.zig92
-rw-r--r--src/bun.js/node/syscall.zig2
3 files changed, 93 insertions, 1 deletions
diff --git a/src/bun.js/WebKit b/src/bun.js/WebKit
-Subproject 4d6ee41032866e63aa43ba007616c632ed1c90a
+Subproject 7d9e2ffa4365e676a4aa96a9941154a68e54f0f
diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig
index 440527e8f..af6e95d26 100644
--- a/src/bun.js/node/node_fs.zig
+++ b/src/bun.js/node/node_fs.zig
@@ -2419,6 +2419,98 @@ pub const NodeFS = struct {
if (args.mode.isForceClone()) {
// https://www.manpagez.com/man/2/clonefile/
return ret.errnoSysP(C.clonefile(src, dest, 0), .clonefile, src) orelse ret.success;
+ } else {
+ const stat_ = switch (Syscall.stat(src)) {
+ .result => |result| result,
+ .err => |err| return Maybe(Return.CopyFile){ .err = err.withPath(src) },
+ };
+
+ if (!os.S.ISREG(stat_.mode)) {
+ return Maybe(Return.CopyFile){ .err = .{ .errno = @enumToInt(C.SystemErrno.ENOTSUP) } };
+ }
+
+ if (stat_.size > 128 * 1024) {
+ if (!args.mode.shouldntOverwrite()) {
+ // clonefile() will fail if it already exists
+ _ = Syscall.unlink(dest);
+ }
+
+ if (ret.errnoSysP(C.clonefile(src, dest, 0), .clonefile, src) == null) {
+ _ = C.chmod(dest, stat_.mode);
+ return ret.success;
+ }
+ } else {
+ const src_fd = switch (Syscall.open(src, std.os.O.RDONLY, 0644)) {
+ .result => |result| result,
+ .err => |err| return .{ .err = err.withPath(args.src.slice()) },
+ };
+ defer {
+ _ = Syscall.close(src_fd);
+ }
+
+ var flags: Mode = std.os.O.CREAT | std.os.O.WRONLY;
+ var wrote: usize = 0;
+ if (args.mode.shouldntOverwrite()) {
+ flags |= std.os.O.EXCL;
+ }
+
+ const dest_fd = switch (Syscall.open(dest, flags, JSC.Node.default_permission)) {
+ .result => |result| result,
+ .err => |err| return Maybe(Return.CopyFile){ .err = err },
+ };
+ defer {
+ _ = std.c.ftruncate(dest_fd, @intCast(std.c.off_t, @truncate(u63, wrote)));
+
+ _ = Syscall.close(dest_fd);
+ }
+
+ var buf: [16384]u8 = undefined;
+ var remain = @intCast(u64, @maximum(stat_.size, 0));
+ toplevel: while (remain > 0) {
+ const amt = switch (Syscall.read(src_fd, buf[0..@minimum(buf.len, remain)])) {
+ .result => |result| result,
+ .err => |err| return Maybe(Return.CopyFile){ .err = err.withPath(src) },
+ };
+ if (amt == 0) {
+ break :toplevel;
+ }
+ wrote += amt;
+ remain -|= amt;
+
+ var slice = buf[0..amt];
+ while (slice.len > 0) {
+ const written = switch (Syscall.write(dest_fd, slice)) {
+ .result => |result| result,
+ .err => |err| return Maybe(Return.CopyFile){ .err = err.withPath(dest) },
+ };
+ if (written == 0) break :toplevel;
+ slice = slice[written..];
+ }
+ } else {
+ outer: while (true) {
+ const amt = switch (Syscall.read(src_fd, &buf)) {
+ .result => |result| result,
+ .err => |err| return Maybe(Return.CopyFile){ .err = err.withPath(src) },
+ };
+ if (amt == 0) {
+ break;
+ }
+ wrote += amt;
+
+ var slice = buf[0..amt];
+ while (slice.len > 0) {
+ const written = switch (Syscall.write(dest_fd, slice)) {
+ .result => |result| result,
+ .err => |err| return Maybe(Return.CopyFile){ .err = err.withPath(dest) },
+ };
+ slice = slice[written..];
+ if (written == 0) break :outer;
+ }
+ }
+ }
+ _ = C.fchmod(dest_fd, stat_.mode);
+ return ret.success;
+ }
}
var mode: Mode = C.darwin.COPYFILE_ACL | C.darwin.COPYFILE_DATA;
diff --git a/src/bun.js/node/syscall.zig b/src/bun.js/node/syscall.zig
index 4378a4762..1f74753d2 100644
--- a/src/bun.js/node/syscall.zig
+++ b/src/bun.js/node/syscall.zig
@@ -419,7 +419,7 @@ pub fn fcopyfile(fd_in: std.os.fd_t, fd_out: std.os.fd_t, flags: u32) Maybe(void
pub fn unlink(from: [:0]const u8) Maybe(void) {
while (true) {
- if (Maybe(void).errno(sys.unlink(from), .unlink)) |err| {
+ if (Maybe(void).errnoSys(sys.unlink(from), .unlink)) |err| {
if (err.getErrno() == .INTR) continue;
return err;
}