diff --git a/src/cache.zig b/src/cache.zig index 021f6e5cd3..2ca746a761 100644 --- a/src/cache.zig +++ b/src/cache.zig @@ -129,10 +129,10 @@ pub const Fs = struct { ) !Entry { var rfs = _fs.fs; - const file_handle: std.fs.File = if (_file_handle) |__file| - std.fs.File{ .handle = __file } + const file_handle: bun.sys.File = if (_file_handle) |__file| + bun.sys.File{ .handle = __file } else - try std.fs.openFileAbsoluteZ(path, .{ .mode = .read_only }); + try bun.sys.File.open(path, bun.sys.O.RDONLY, 0).unwrap(); defer { if (rfs.needToCloseFiles() and _file_handle == null) { @@ -183,11 +183,11 @@ pub const Fs = struct { ) !Entry { var rfs = _fs.fs; - var file_handle: std.fs.File = if (_file_handle) |__file| __file.asFile() else undefined; + var file_handle: bun.sys.File = if (_file_handle) |__file| bun.sys.File{ .handle = __file } else undefined; if (_file_handle == null) { if (FeatureFlags.store_file_descriptors and dirname_fd != bun.invalid_fd and dirname_fd != .zero) { - file_handle = (bun.sys.openatA(dirname_fd, std.fs.path.basename(path), bun.O.RDONLY, 0).unwrap() catch |err| brk: { + file_handle = .{ .handle = (bun.sys.openatA(dirname_fd, std.fs.path.basename(path), bun.O.RDONLY, 0).unwrap() catch |err| brk: { switch (err) { error.ENOENT => { const handle = try bun.openFile(path, .{ .mode = .read_only }); @@ -199,9 +199,9 @@ pub const Fs = struct { }, else => return err, } - }).asFile(); + }) }; } else { - file_handle = try bun.openFile(path, .{ .mode = .read_only }); + file_handle = .{ .handle = try bun.sys.openA(path, bun.sys.O.RDONLY, 0).unwrap() }; } } @@ -211,7 +211,6 @@ pub const Fs = struct { const will_close = rfs.needToCloseFiles() and _file_handle == null; defer { if (will_close) { - debug("readFileWithAllocator close({d})", .{file_handle.handle}); file_handle.close(); } } diff --git a/src/fs.zig b/src/fs.zig index e2ddb57fdb..5b2b192edb 100644 --- a/src/fs.zig +++ b/src/fs.zig @@ -1135,7 +1135,7 @@ pub const FileSystem = struct { fs: *RealFS, path: string, _size: ?usize, - file: std.fs.File, + file: bun.sys.File, comptime use_shared_buffer: bool, shared_buffer: *MutableString, comptime stream: bool, @@ -1157,19 +1157,18 @@ pub const FileSystem = struct { allocator: std.mem.Allocator, path: string, _size: ?usize, - file: std.fs.File, + file: bun.sys.File, comptime use_shared_buffer: bool, shared_buffer: *MutableString, comptime stream: bool, ) !PathContentsPair { - FileSystem.setMaxFd(file.handle); + if (comptime Environment.isPosix) { + FileSystem.setMaxFd(file.handle.int()); + } // Skip the extra file.stat() call when possible - var size = _size orelse (file.getEndPos() catch |err| { - fs.readFileError(path, err); - return err; - }); - debug("stat({d}) = {d}", .{ file.handle, size }); + var size = _size orelse try file.getEndPos().unwrap(); + debug("stat({}) = {d}", .{ file.handle, size }); // Skip the pread call for empty files // Otherwise will get out of bounds errors @@ -1203,14 +1202,10 @@ pub const FileSystem = struct { // We use pread to ensure if the file handle was open, it doesn't seek from the last position const prev_file_pos = if (comptime Environment.isWindows) try file.getPos() else 0; - const read_count = file.preadAll(shared_buffer.list.items[offset..], offset) catch |err| { - fs.readFileError(path, err); - return err; - }; - if (comptime Environment.isWindows) try file.seekTo(prev_file_pos); - shared_buffer.list.items = shared_buffer.list.items[0 .. read_count + offset]; + const read_amount = try file.preadAll(shared_buffer.list.items[offset..], offset).unwrap(); + if (comptime Environment.isWindows) try file.seekTo(@intCast(prev_file_pos)); + shared_buffer.list.items = shared_buffer.list.items[0 .. read_amount + offset]; file_contents = shared_buffer.list.items; - debug("pread({d}, {d}) = {d}", .{ file.handle, size, read_count }); if (comptime stream) { // check again that stat() didn't change the file size @@ -1220,11 +1215,10 @@ pub const FileSystem = struct { return err; }; - offset += read_count; + offset += read_amount; // don't infinite loop is we're still not reading more - if (read_count == 0) break; - + if (read_amount == 0) break; if (offset < new_size) { try shared_buffer.growBy(new_size - size); shared_buffer.list.expandToCapacity(); @@ -1251,13 +1245,9 @@ pub const FileSystem = struct { buf[size] = 0; const prev_file_pos = if (comptime Environment.isWindows) try file.getPos() else 0; - const read_count = file.preadAll(buf, 0) catch |err| { - fs.readFileError(path, err); - return err; - }; + const read_buf = try file.preadAll(buf, 0).unwrap(); if (comptime Environment.isWindows) try file.seekTo(prev_file_pos); - file_contents = buf[0..read_count]; - debug("pread({d}, {d}) = {d}", .{ file.handle, size, read_count }); + file_contents = buf[0..read_buf]; if (strings.BOM.detect(file_contents)) |bom| { debug("Convert {s} BOM", .{@tagName(bom)}); @@ -1268,60 +1258,6 @@ pub const FileSystem = struct { return PathContentsPair{ .path = Path.init(path), .contents = file_contents }; } - pub fn kindFromAbsolute( - fs: *RealFS, - absolute_path: [:0]const u8, - existing_fd: StoredFileDescriptorType, - store_fd: bool, - ) !Entry.Cache { - var outpath: bun.PathBuffer = undefined; - - const stat = try C.lstat_absolute(absolute_path); - const is_symlink = stat.kind == std.fs.File.Kind.SymLink; - var _kind = stat.kind; - var cache = Entry.Cache{ - .kind = Entry.Kind.file, - .symlink = PathString.empty, - }; - var symlink: []const u8 = ""; - - if (is_symlink) { - var file = try if (existing_fd != 0) - std.fs.File{ .handle = existing_fd } - else if (store_fd) - std.fs.openFileAbsoluteZ(absolute_path, .{ .mode = .read_only }) - else - bun.openFileForPath(absolute_path); - setMaxFd(file.handle); - - defer { - if ((!store_fd or fs.needToCloseFiles()) and existing_fd == 0) { - file.close(); - } else if (comptime FeatureFlags.store_file_descriptors) { - cache.fd = file.handle; - } - } - const _stat = try file.stat(); - - symlink = try bun.getFdPath(file.handle, &outpath); - - _kind = _stat.kind; - } - - bun.assert(_kind != .SymLink); - - if (_kind == .Directory) { - cache.kind = .dir; - } else { - cache.kind = .file; - } - if (symlink.len > 0) { - cache.symlink = PathString.init(try FilenameStore.instance.append([]const u8, symlink)); - } - - return cache; - } - pub fn kind( fs: *RealFS, _dir: string, diff --git a/src/sys.zig b/src/sys.zig index d0ae1fdd4d..6f9de2548d 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -4015,6 +4015,41 @@ pub const File = struct { } }; + pub fn pread(this: File, buf: []u8, offset: usize) Maybe(usize) { + return bun.sys.pread(this.handle, buf, @intCast(offset)); + } + + pub fn seekTo(this: File, offset: i64) Maybe(void) { + if (comptime Environment.isWindows) { + const rc = std.os.windows.kernel32.SetFilePointerEx(this.handle.cast(), offset, null, std.os.windows.FILE_BEGIN); + if (Maybe(void).errnoSys(rc, .lseek)) |err| { + return err; + } + + return .{ .result = {} }; + } + + return bun.sys.lseek(this.handle, offset, std.posix.SEEK.SET); + } + + pub fn preadAll(this: File, buf: []u8, offset: usize) Maybe(usize) { + var total: usize = 0; + while (true) { + const read_amount = switch (this.pread(buf[total..], offset + total)) { + .err => |err| return .{ .err = err }, + .result => |amt| amt, + }; + + if (read_amount == 0) { + break; + } + + total += read_amount; + } + + return .{ .result = total }; + } + pub fn readFillBuf(this: File, buf: []u8) Maybe([]u8) { var read_amount: usize = 0; while (read_amount < buf.len) {