diff options
Diffstat (limited to 'src')
| m--------- | src/bun.js/WebKit | 0 | ||||
| -rw-r--r-- | src/bun.js/node/node_fs.zig | 92 | ||||
| -rw-r--r-- | src/bun.js/node/syscall.zig | 2 | 
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;          } | 
