diff options
Diffstat (limited to 'src/fs.zig')
-rw-r--r-- | src/fs.zig | 74 |
1 files changed, 64 insertions, 10 deletions
diff --git a/src/fs.zig b/src/fs.zig index 2dca8169c..98174fac3 100644 --- a/src/fs.zig +++ b/src/fs.zig @@ -157,10 +157,10 @@ pub const FileSystem = struct { pub fn addEntry(dir: *DirEntry, prev_map: ?*EntryMap, entry: std.fs.IterableDir.Entry, allocator: std.mem.Allocator, comptime Iterator: type, iterator: Iterator) !void { const _kind: Entry.Kind = switch (entry.kind) { - .Directory => .dir, + .directory => .dir, // This might be wrong! - .SymLink => .file, - .File => .file, + .sym_link => .file, + .file => .file, else => return, }; @@ -207,7 +207,7 @@ pub const FileSystem = struct { // Call "stat" lazily for performance. The "@material-ui/icons" package // contains a directory with over 11,000 entries in it and running "stat" // for each entry was a big performance issue for that package. - .need_stat = entry.kind == .SymLink, + .need_stat = entry.kind == .sym_link, .cache = .{ .symlink = PathString.empty, .kind = _kind, @@ -768,7 +768,7 @@ pub const FileSystem = struct { hash_bytes_remain = hash_bytes_remain[@sizeOf(@TypeOf(this.mtime))..]; std.debug.assert(hash_bytes_remain.len == 8); hash_bytes_remain[0..8].* = @bitCast([8]u8, @as(u64, 0)); - return std.hash.Wyhash.hash(0, &hash_bytes); + return bun.hash(&hash_bytes); } pub fn generate(_: *RealFS, _: string, file: std.fs.File) anyerror!ModKey { @@ -1109,6 +1109,60 @@ pub const FileSystem = struct { return File{ .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.MAX_PATH_BYTES]u8 = undefined; + + var 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; + } + + std.debug.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, @@ -1127,7 +1181,7 @@ pub const FileSystem = struct { const absolute_path_c: [:0]const u8 = outpath[0..entry_path.len :0]; var stat = try C.lstat_absolute(absolute_path_c); - const is_symlink = stat.kind == std.fs.File.Kind.SymLink; + const is_symlink = stat.kind == std.fs.File.Kind.sym_link; var _kind = stat.kind; var cache = Entry.Cache{ .kind = Entry.Kind.file, @@ -1158,9 +1212,9 @@ pub const FileSystem = struct { _kind = _stat.kind; } - std.debug.assert(_kind != .SymLink); + std.debug.assert(_kind != .sym_link); - if (_kind == .Directory) { + if (_kind == .directory) { cache.kind = .dir; } else { cache.kind = .file; @@ -1318,8 +1372,8 @@ pub const PathName = struct { // so we extend the original slice's length by one return if (this.dir.len == 0) "./" else this.dir.ptr[0 .. this.dir.len + @intCast( usize, - @boolToInt( - this.dir[this.dir.len - 1] != std.fs.path.sep_posix and (@ptrToInt(this.dir.ptr) + this.dir.len + 1) == @ptrToInt(this.base.ptr), + @intFromBool( + this.dir[this.dir.len - 1] != std.fs.path.sep_posix and (@intFromPtr(this.dir.ptr) + this.dir.len + 1) == @intFromPtr(this.base.ptr), ), )]; } |