diff options
author | Daan De Meyer <daan.j.demeyer@gmail.com> | 2022-11-24 13:13:21 +0100 |
---|---|---|
committer | Daan De Meyer <daan.j.demeyer@gmail.com> | 2022-11-24 14:02:19 +0100 |
commit | a0a4c57818ac9137e7fe2903b6f2a032fca9292e (patch) | |
tree | 602b418609fddbe2eb880f675449285cdc4f5b11 /src | |
parent | 06da125ea19284a5200e206e704a37c17dbbab5e (diff) | |
download | systemd-a0a4c57818ac9137e7fe2903b6f2a032fca9292e.tar.gz |
recurse-dir: Handle RECURSE_DIR_ENSURE_TYPE in readdir_all()
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/recurse-dir.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/src/basic/recurse-dir.c b/src/basic/recurse-dir.c index 908e833501..fe18b98d5b 100644 --- a/src/basic/recurse-dir.c +++ b/src/basic/recurse-dir.c @@ -33,6 +33,7 @@ int readdir_all(int dir_fd, struct dirent *entry; DirectoryEntries *nde; size_t add, sz, j; + int r; assert(dir_fd >= 0); @@ -84,6 +85,15 @@ int readdir_all(int dir_fd, if (ignore_dirent(entry, flags)) continue; + if (FLAGS_SET(flags, RECURSE_DIR_ENSURE_TYPE)) { + r = dirent_ensure_type(dir_fd, entry); + if (r == -ENOENT) + /* dentry gone by now? no problem, let's just suppress it */ + continue; + if (r < 0) + return r; + } + de->n_entries++; } @@ -104,8 +114,14 @@ int readdir_all(int dir_fd, if (ignore_dirent(entry, flags)) continue; + /* If d_type == DT_UNKNOWN that means we failed to ensure the type in the earlier loop and + * didn't include the dentry in de->n_entries and as such should skip it here as well. */ + if (FLAGS_SET(flags, RECURSE_DIR_ENSURE_TYPE) && entry->d_type == DT_UNKNOWN) + continue; + de->entries[j++] = entry; } + assert(j == de->n_entries); if (FLAGS_SET(flags, RECURSE_DIR_SORT)) typesafe_qsort(de->entries, de->n_entries, sort_func); @@ -160,7 +176,8 @@ int recurse_dir( return r; } - r = readdir_all(dir_fd, flags, &de); + /* Mask out RECURSE_DIR_ENSURE_TYPE so we can do it ourselves and avoid an extra statx() call. */ + r = readdir_all(dir_fd, flags & ~RECURSE_DIR_ENSURE_TYPE, &de); if (r < 0) return r; |