From: Petr Tesarik <ptesarik@suse.com>
Subject: Pass dirfd to ListDirFilter::test()
References: bsc#964206
Patch-mainline: v0.8.16
Git-commit: 65a57ec068514441edcbfd30b93f86466f1113d9

If the test() needs to stat() or open() the file, a pointer to the
parent directory must be provided.

Note that this also removes the ugly workaround for FilterKdumpDirs.

Signed-off-by: Petr Tesarik <ptesarik@suse.com>
---
 kdumptool/calibrate.cc   |    2 +-
 kdumptool/deletedumps.cc |    2 +-
 kdumptool/fileutil.cc    |   18 +++++++++---------
 kdumptool/fileutil.h     |   15 ++++-----------
 kdumptool/testlistdir.cc |    2 +-
 5 files changed, 16 insertions(+), 23 deletions(-)

--- a/kdumptool/deletedumps.cc
+++ b/kdumptool/deletedumps.cc
@@ -110,7 +110,7 @@ void DeleteDumps::delete_one(const RootD
         return;
     }
 
-    StringVector contents = dir.listDir(FilterKdumpDirs(dir));
+    StringVector contents = dir.listDir(FilterKdumpDirs());
     int deleteItems;
     if (oldDumps == -1)
         deleteItems = contents.size();
--- a/kdumptool/fileutil.cc
+++ b/kdumptool/fileutil.cc
@@ -312,7 +312,7 @@ StringVector FilePath::listDir(const Lis
 
 	errno = 0;
 	while ( (d = readdir(dirp)) ) {
-	    if (filter.test(d))
+	    if (filter.test(dirfd(dirp), d))
 		v.push_back(d->d_name);
 	    errno = 0;
 	}
@@ -433,7 +433,7 @@ void FilePath::rmdir(bool recursive)
 //{{{ FilterDots ---------------------------------------------------------------
 
 // -----------------------------------------------------------------------------
-bool FilterDots::test(const struct dirent *d) const
+bool FilterDots::test(int dirfd, const struct dirent *d) const
 {
     if (strcmp(d->d_name, ".") == 0)
         return false;
@@ -447,24 +447,24 @@ bool FilterDots::test(const struct diren
 //{{{ FilterDotsAndNondirs -----------------------------------------------------
 
 // -----------------------------------------------------------------------------
-bool FilterDotsAndNondirs::test(const struct dirent *d) const
+bool FilterDotsAndNondirs::test(int dirfd, const struct dirent *d) const
 {
-    return FilterDots::test(d) && d->d_type == DT_DIR;
+    return FilterDots::test(dirfd, d) && d->d_type == DT_DIR;
 }
 //}}}
 
 //{{{ FilterKdumpDirs ----------------------------------------------------------
 
 // -----------------------------------------------------------------------------
-bool FilterKdumpDirs::test(const struct dirent *d) const
+bool FilterKdumpDirs::test(int dirfd, const struct dirent *d) const
 {
-    if (!FilterDotsAndNondirs::test(d))
+    if (!FilterDotsAndNondirs::test(dirfd, d))
 	return false;
 
-    FilePath vmcore(m_path);
-    vmcore.appendPath(d->d_name);
+    struct stat mystat;
+    FilePath vmcore(d->d_name);
     vmcore.appendPath("vmcore");
-    return vmcore.exists();
+    return fstatat(dirfd, vmcore.c_str(), &mystat, 0) == 0;
 }
 //}}}
 
--- a/kdumptool/testlistdir.cc
+++ b/kdumptool/testlistdir.cc
@@ -52,7 +52,7 @@ int main(int argc, char *argv[])
     else if (mode == "dirs")
 	filt = new FilterDotsAndNondirs();
     else if (mode == "kdumpdirs")
-	filt = new FilterKdumpDirs(dir);
+	filt = new FilterKdumpDirs();
     else {
 	cerr << "Mode must be one of: 'all', 'dirs', 'kdumpdirs'" << endl;
 	return EXIT_FAILURE;
--- a/kdumptool/fileutil.h
+++ b/kdumptool/fileutil.h
@@ -91,7 +91,7 @@ class ListDirFilter {
 	virtual ~ListDirFilter()
 	{}
 
-	virtual bool test(const struct dirent *d) const = 0;
+	virtual bool test(int dirfd, const struct dirent *d) const = 0;
 };
 //}}}
 //{{{ FilePath -----------------------------------------------------------------
@@ -267,7 +267,7 @@ class FilterDots : public ListDirFilter
 	virtual ~FilterDots()
 	{}
 
-	bool test(const struct dirent *d) const;
+	bool test(int dirfd, const struct dirent *d) const;
 };
 //}}}
 //{{{ FilterDotsAndNondirs -----------------------------------------------------
@@ -277,24 +277,17 @@ class FilterDotsAndNondirs : public Filt
 	virtual ~FilterDotsAndNondirs()
 	{}
 
-	bool test(const struct dirent *d) const;
+	bool test(int dirfd, const struct dirent *d) const;
 };
 //}}}
 //{{{ FilterKdumpDirs ----------------------------------------------------------
 class FilterKdumpDirs : public FilterDotsAndNondirs {
 
     public:
-	FilterKdumpDirs(const std::string &path)
-	    : m_path(path)
-	{}
-
 	virtual ~FilterKdumpDirs()
 	{}
 
-	bool test(const struct dirent *d) const;
-
-    private:
-	const std::string m_path;
+	bool test(int dirfd, const struct dirent *d) const;
 };
 //}}}
 //{{{ Functions ----------------------------------------------------------------
--- a/kdumptool/calibrate.cc
+++ b/kdumptool/calibrate.cc
@@ -432,7 +432,7 @@ class Framebuffers {
 		virtual ~DirFilter()
 		{}
 
-		bool test(const struct dirent *d) const
+		bool test(int dirfd, const struct dirent *d) const
 		{
 		    char *end;
 		    if (strncmp(d->d_name, "fb", 2))
