From 983b17d68d55687549d0484e2c9d739bbdbfc753 Mon Sep 17 00:00:00 2001 From: Dmitry Rozhkov Date: Fri, 10 Jun 2016 11:17:15 +0300 Subject: [PATCH] Resort to lstat for FS not supporting dirent.d_type According to POSIX.1 only d_name and d_ino fields of struct dirent are standardized. d_type isn't always correctly set on file systems like XFS. In such cases it makes sense to resort to lstat(). Otherwise a user has hard time figuring out what's wrong with her setup. Also remove redundant populate_file_struct() as it's called again in parallel threads. Signed-off-by: Dmitry Rozhkov --- src/analyze_fs.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/analyze_fs.c b/src/analyze_fs.c index a40b086..c7585e2 100644 --- a/src/analyze_fs.c +++ b/src/analyze_fs.c @@ -321,7 +321,6 @@ static void iterate_directory(struct manifest *manifest, char *pathprefix, while (dir) { struct file *file; char *sub_filename; - char *fullname; entry = readdir(dir); if (!entry) { @@ -349,12 +348,22 @@ static void iterate_directory(struct manifest *manifest, char *pathprefix, file->last_change = manifest->version; file->filename = sub_filename; - string_or_die(&fullname, "%s/%s", fullpath, entry->d_name); - populate_file_struct(file, fullname); - free(fullname); - if (entry->d_type == DT_DIR) { iterate_directory(manifest, pathprefix, file->filename, do_hash); + } else if (entry->d_type == DT_UNKNOWN) { /* fall back to lstat() */ + struct stat sb; + char *fullname; + + string_or_die(&fullname, "%s/%s", fullpath, entry->d_name); + if (lstat(fullname, &sb) == -1) { + perror("lstat"); + assert(0); + } + free(fullname); + + if (S_ISDIR(sb.st_mode)) { + iterate_directory(manifest, pathprefix, file->filename, do_hash); + } } /* if for some reason there is a file in the official build