From f35043552d6ae595cc2fedc04552bf7a3c9d3ef5 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Mon, 15 Apr 2024 18:40:12 -0700 Subject: [PATCH] Use our slightly more tolerant methods for writing to the manifest cache --- src/c.zig | 4 ---- src/install/npm.zig | 39 +++++++++++++++++---------------------- src/sys.zig | 6 +++++- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/c.zig b/src/c.zig index 5e74b804f34860..167b94b6ad4faf 100644 --- a/src/c.zig +++ b/src/c.zig @@ -157,10 +157,6 @@ pub fn moveFileZSlow(from_dir: bun.FileDescriptor, filename: [:0]const u8, to_di } pub fn copyFileZSlowWithHandle(in_handle: bun.FileDescriptor, to_dir: bun.FileDescriptor, destination: [:0]const u8) !void { - if (comptime Environment.isWindows) { - @panic("TODO windows"); - } - const stat_ = if (comptime Environment.isPosix) try std.os.fstat(in_handle.cast()) else void{}; // Attempt to delete incase it already existed. diff --git a/src/install/npm.zig b/src/install/npm.zig index 8df30abf62f6c9..893465fa4866a8 100644 --- a/src/install/npm.zig +++ b/src/install/npm.zig @@ -657,13 +657,21 @@ pub const PackageManifest = struct { } } - fn writeFile(this: *const PackageManifest, tmp_path: [:0]const u8, tmpdir: std.fs.Dir) !void { - var tmpfile = try tmpdir.createFileZ(tmp_path, .{ - .truncate = true, - }); - defer tmpfile.close(); - const writer = tmpfile.writer(); - try Serializer.write(this, @TypeOf(writer), writer); + fn writeFile( + this: *const PackageManifest, + tmpdir: anytype, + tmp_path: [:0]const u8, + cache_dir: anytype, + out_path: [:0]const u8, + ) !void { + var tmpfile = try bun.sys.File.openat(tmpdir, tmp_path, std.os.O.CREAT | std.os.O.TRUNC | std.os.O.WRONLY, 0).unwrap(); + { + errdefer tmpfile.close(); + const writer = tmpfile.writer(); + try Serializer.write(this, @TypeOf(writer), writer); + } + + try tmpfile.closeAndMoveAt(tmpdir, tmp_path, cache_dir, out_path); } pub fn save(this: *const PackageManifest, tmpdir: std.fs.Dir, cache_dir: std.fs.Dir) !void { @@ -678,9 +686,8 @@ pub const PackageManifest = struct { try dest_path_stream_writer.print("{any}.npm-{any}", .{ hex_fmt, hex_timestamp_fmt }); try dest_path_stream_writer.writeByte(0); const tmp_path: [:0]u8 = dest_path_buf[0 .. dest_path_stream.pos - 1 :0]; - try writeFile(this, tmp_path, tmpdir); const out_path = std.fmt.bufPrintZ(&out_path_buf, "{any}.npm", .{hex_fmt}) catch unreachable; - try std.os.renameatZ(tmpdir.fd, tmp_path, cache_dir.fd, out_path); + try writeFile(this, tmpdir, tmp_path, cache_dir, out_path); } pub fn load(allocator: std.mem.Allocator, cache_dir: std.fs.Dir, package_name: string) !?PackageManifest { @@ -688,23 +695,11 @@ pub const PackageManifest = struct { var file_path_buf: [512 + 64]u8 = undefined; const hex_fmt = bun.fmt.hexIntLower(file_id); const file_path = try std.fmt.bufPrintZ(&file_path_buf, "{any}.npm", .{hex_fmt}); - var cache_file = cache_dir.openFileZ( - file_path, - .{ .mode = .read_only }, - ) catch return null; var timer: std.time.Timer = undefined; if (PackageManager.verbose_install) { timer = std.time.Timer.start() catch @panic("timer fail"); } - defer cache_file.close(); - const bytes = try cache_file.readToEndAllocOptions( - allocator, - std.math.maxInt(u32), - cache_file.getEndPos() catch null, - @alignOf(u8), - null, - ); - + const bytes = bun.sys.File.readFrom(cache_dir, file_path, allocator).unwrap() catch return null; errdefer allocator.free(bytes); if (bytes.len < header_bytes.len) return null; const result = try readAll(bytes); diff --git a/src/sys.zig b/src/sys.zig index 270369fb97cc24..552eb5dec154a6 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -2632,11 +2632,15 @@ pub const File = struct { pub const ReadError = anyerror; pub fn closeAndMoveTo(this: File, src: [:0]const u8, dest: [:0]const u8) !void { + return closeAndMoveAt(this, std.fs.cwd(), src, std.fs.cwd(), dest); + } + + pub fn closeAndMoveAt(this: File, src_dir: anytype, src: [:0]const u8, dest_dir: anytype, dest: [:0]const u8) !void { // On POSIX, close the file after moving it. defer if (Environment.isPosix) this.close(); // On Windows, close the file before moving it. if (Environment.isWindows) this.close(); - try bun.C.moveFileZWithHandle(this.handle, bun.toFD(std.fs.cwd()), src, bun.toFD(std.fs.cwd()), dest); + try bun.C.moveFileZWithHandle(this.handle, bun.toFD(src_dir), src, bun.toFD(dest_dir), dest); } fn stdIoRead(this: File, buf: []u8) ReadError!usize {