Repository navigation
bun test: scan each directory once, however many symlinks lead to it #44487
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -114,6 +114,26 @@ pub struct EntryCache { | |
| /// don't make it bun.invalid_fd | ||
| pub fd: Fd, | ||
| pub(crate) kind: EntryKind, | ||
| /// The entry is itself a link (a POSIX symlink, a Windows reparse point). | ||
| /// `symlink` alone does not say so: the resolver also fills it for real directories. | ||
| pub(crate) is_link: bool, | ||
| } | ||
|
|
||
| // `is_link` sits in what was padding after `kind`. | ||
| const _: () = assert!( | ||
| size_of::<EntryCache>() | ||
| == (size_of::<Interned>() + size_of::<Fd>() + size_of::<EntryKind>()) | ||
| .next_multiple_of(align_of::<EntryCache>()) | ||
| ); | ||
|
|
||
| /// What a directory walker needs to know about an entry, from one read of its stat cache. | ||
| #[derive(Clone, Copy)] | ||
| pub struct EntryLink { | ||
| pub kind: EntryKind, | ||
| pub is_link: bool, | ||
| /// Where the link leads, with every link on the way resolved. Empty when | ||
| /// the entry is not a link or its target could not be named. | ||
|
Comment on lines
+134
to
+135
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you need a paragraph-long comment to justify why the workaround is OK, the code is wrong — fix the code |
||
| pub real_path: &'static [u8], | ||
| } | ||
|
|
||
| // `cache` / `need_stat` are lazily populated by `Entry::kind` / | ||
|
|
@@ -234,6 +254,25 @@ impl Entry { | |
| self.cache().kind | ||
| } | ||
|
|
||
| /// [`Entry::kind`], plus whether the entry is a link and where it leads. | ||
| /// | ||
| /// # Safety | ||
| /// Same contract as [`Entry::kind`]. | ||
|
Comment on lines
+257
to
+260
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you need a paragraph-long comment to justify why the workaround is OK, the code is wrong — fix the code |
||
| pub unsafe fn link<R: EntryKindResolver>(&self, fs: *mut R, store_fd: bool) -> EntryLink { | ||
| // SAFETY: forwarded; `kind` runs the stat-on-first-use protocol. | ||
| let _ = unsafe { self.kind(fs, store_fd) }; | ||
| let cache = self.cache(); | ||
| EntryLink { | ||
| kind: cache.kind, | ||
| is_link: cache.is_link, | ||
| real_path: if cache.is_link { | ||
| cache.symlink.as_bytes() | ||
| } else { | ||
| b"" | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| /// | ||
| /// # Safety | ||
| /// `fs` must point to a live `EntryKindResolver` (the process-global | ||
|
|
@@ -537,6 +576,7 @@ impl DirEntry { | |
| // store an arbitrary kind | ||
| kind: found_kind.unwrap_or(EntryKind::File), | ||
| fd: Fd::INVALID, | ||
| is_link: false, | ||
| })); | ||
| addr_of_mut!((*p).abs_path).write(Interned::EMPTY); | ||
| p | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you need a paragraph-long comment to justify why the workaround is OK, the code is wrong — fix the code