/** Skip ".", "..", and deleted/empty dirents. */
static int bfs_skipdent(struct bfs_dir *dir, const sys_dirent *de) {
-#if BFS_USE_GETDENTS && __FreeBSD__
+#if BFS_USE_GETDENTS
+# if __FreeBSD__
// Union mounts on FreeBSD have to be de-duplicated in userspace
if (dir->flags & BFS_DIR_UNION) {
struct trie_leaf *leaf = trie_insert_str(&dir->trie, de->d_name);
if (de->d_ino == 0) {
return 1;
}
-#endif
+# endif
+
+# ifdef DT_WHT
+ if (de->d_type == DT_WHT && !(dir->flags & BFS_DIR_WHITEOUTS)) {
+ return 1;
+ }
+# endif
+#endif // BFS_USE_GETDENTS
const char *name = de->d_name;
return name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'));
* bfs_opendir() flags.
*/
enum bfs_dir_flags {
+ /** Include whiteouts in the results. */
+ BFS_DIR_WHITEOUTS = 1 << 0,
/** @internal Start of private flags. */
- BFS_DIR_PRIVATE = 1 << 0,
+ BFS_DIR_PRIVATE = 1 << 1,
};
/**