From 40c690d03b44fdbddb28ea9988b24c2356807a82 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Tue, 10 Mar 2015 21:51:12 +0100 Subject: [PATCH] Dir::children() returns not only the entry name, but also whether it is a file or a directory entry --- fs_interface/Dir.h | 15 ++++++++++++++- fuse/Filesystem.h | 4 +++- fuse/Fuse.cpp | 2 +- impl/FilesystemImpl.cpp | 2 +- impl/FilesystemImpl.h | 3 +-- test/fuse/readDir/FuseReadDirReturnTest.cpp | 1 + test/fuse/readDir/testutils/FuseReadDirTest.cpp | 7 +++++-- test/fuse/readDir/testutils/FuseReadDirTest.h | 3 ++- test/testutils/FuseTest.h | 7 ++++--- 9 files changed, 32 insertions(+), 12 deletions(-) diff --git a/fs_interface/Dir.h b/fs_interface/Dir.h index 26ef33cd..f495fc75 100644 --- a/fs_interface/Dir.h +++ b/fs_interface/Dir.h @@ -14,11 +14,24 @@ class Dir: public virtual Node { public: virtual ~Dir() {} + enum class EntryType { + DIR = 0, + FILE = 1 + }; + + struct Entry { + Entry(EntryType type_, const std::string &name_): type(type_), name(name_) {} + EntryType type; + std::string name; + }; + virtual std::unique_ptr createFile(const std::string &name, mode_t mode) = 0; virtual std::unique_ptr createDir(const std::string &name, mode_t mode) = 0; virtual void rmdir() = 0; - virtual std::unique_ptr> children() const = 0; + //TODO Allow alternative implementation returning only children names without more information + //virtual std::unique_ptr> children() const = 0; + virtual std::unique_ptr> children() const = 0; }; } /* namespace fspp */ diff --git a/fuse/Filesystem.h b/fuse/Filesystem.h index 11995377..91a62135 100644 --- a/fuse/Filesystem.h +++ b/fuse/Filesystem.h @@ -6,6 +6,7 @@ #include #include #include +#include "../fs_interface/Dir.h" namespace fspp { namespace fuse { @@ -32,7 +33,8 @@ public: virtual void rename(const boost::filesystem::path &from, const boost::filesystem::path &to) = 0; virtual void utimens(const boost::filesystem::path &path, const timespec times[2]) = 0; virtual void statfs(const boost::filesystem::path &path, struct statvfs *fsstat) = 0; - virtual std::unique_ptr> readDir(const boost::filesystem::path &path) = 0; + //TODO We shouldn't use Dir::Entry here, that's in another layer + virtual std::unique_ptr> readDir(const boost::filesystem::path &path) = 0; }; } diff --git a/fuse/Fuse.cpp b/fuse/Fuse.cpp index 2fef11c9..f15ac122 100644 --- a/fuse/Fuse.cpp +++ b/fuse/Fuse.cpp @@ -472,7 +472,7 @@ int Fuse::readdir(const bf::path &path, void *buf, fuse_fill_dir_t filler, off_t //We could pass file metadata to filler() in its third parameter, //but it doesn't help performance since fuse seems to ignore it. //It does getattr() calls on all entries nevertheless. - if (filler(buf, entry.c_str(), nullptr, 0) != 0) { + if (filler(buf, entry.name.c_str(), nullptr, 0) != 0) { return -ENOMEM; } } diff --git a/impl/FilesystemImpl.cpp b/impl/FilesystemImpl.cpp index f25d9310..e0ca905a 100644 --- a/impl/FilesystemImpl.cpp +++ b/impl/FilesystemImpl.cpp @@ -127,7 +127,7 @@ void FilesystemImpl::rename(const bf::path &from, const bf::path &to) { node->rename(to); } -unique_ptr> FilesystemImpl::readDir(const bf::path &path) { +unique_ptr> FilesystemImpl::readDir(const bf::path &path) { auto dir = LoadDir(path); return dir->children(); } diff --git a/impl/FilesystemImpl.h b/impl/FilesystemImpl.h index 8ee09b42..85c55d5b 100644 --- a/impl/FilesystemImpl.h +++ b/impl/FilesystemImpl.h @@ -11,7 +11,6 @@ namespace fspp { class Node; class File; class OpenFile; -class Dir; class FilesystemImpl: public fuse::Filesystem { public: @@ -35,7 +34,7 @@ public: void rmdir(const boost::filesystem::path &path) override; void unlink(const boost::filesystem::path &path) override; void rename(const boost::filesystem::path &from, const boost::filesystem::path &to) override; - std::unique_ptr> readDir(const boost::filesystem::path &path) override; + std::unique_ptr> readDir(const boost::filesystem::path &path) override; void utimens(const boost::filesystem::path &path, const timespec times[2]) override; void statfs(const boost::filesystem::path &path, struct statvfs *fsstat) override; diff --git a/test/fuse/readDir/FuseReadDirReturnTest.cpp b/test/fuse/readDir/FuseReadDirReturnTest.cpp index 05cc57a6..0a9dddcb 100644 --- a/test/fuse/readDir/FuseReadDirReturnTest.cpp +++ b/test/fuse/readDir/FuseReadDirReturnTest.cpp @@ -14,6 +14,7 @@ using std::vector; using std::string; using namespace fspp::fuse; +using fspp::Dir; unique_ptr> LARGE_DIR(int num_entries) { auto result = make_unique>(); diff --git a/test/fuse/readDir/testutils/FuseReadDirTest.cpp b/test/fuse/readDir/testutils/FuseReadDirTest.cpp index c60caf37..92aaff1a 100644 --- a/test/fuse/readDir/testutils/FuseReadDirTest.cpp +++ b/test/fuse/readDir/testutils/FuseReadDirTest.cpp @@ -79,7 +79,10 @@ void FuseReadDirTest::closeDir(DIR *dir) { EXPECT_EQ(0, retval) << "Closing dir failed"; } -Action*(const char*)> FuseReadDirTest::ReturnDirEntries(vector entries) { - vector *direntries = new vector(entries); +Action*(const char*)> FuseReadDirTest::ReturnDirEntries(vector entries) { + vector *direntries = new vector(entries.size(), fspp::Dir::Entry(fspp::Dir::EntryType::FILE, "")); + for(unsigned int i = 0; i < entries.size(); ++i) { + (*direntries)[i].name = entries[i]; + } return Return(direntries); } diff --git a/test/fuse/readDir/testutils/FuseReadDirTest.h b/test/fuse/readDir/testutils/FuseReadDirTest.h index d365967f..de6c0b95 100644 --- a/test/fuse/readDir/testutils/FuseReadDirTest.h +++ b/test/fuse/readDir/testutils/FuseReadDirTest.h @@ -4,6 +4,7 @@ #include "../../../testutils/FuseTest.h" #include +#include "../../../../fs_interface/Dir.h" class FuseReadDirTest: public FuseTest { public: @@ -12,7 +13,7 @@ public: std::unique_ptr> ReadDir(const char *dirname); int ReadDirReturnError(const char *dirname); - static ::testing::Action*(const char*)> ReturnDirEntries(std::vector entries); + static ::testing::Action*(const char*)> ReturnDirEntries(std::vector entries); private: DIR *openDir(TempTestFS *fs, const char *dirname); diff --git a/test/testutils/FuseTest.h b/test/testutils/FuseTest.h index 13aa73b8..d89e2266 100644 --- a/test/testutils/FuseTest.h +++ b/test/testutils/FuseTest.h @@ -8,6 +8,7 @@ #include "../../fuse/Filesystem.h" #include "../../fuse/FuseErrnoException.h" #include "../../fuse/Fuse.h" +#include "../../fs_interface/Dir.h" #include @@ -57,10 +58,10 @@ public: return rename(from.c_str(), to.c_str()); } MOCK_METHOD2(rename, void(const char*, const char*)); - std::unique_ptr> readDir(const boost::filesystem::path &path) { - return std::unique_ptr>(readDir(path.c_str())); + std::unique_ptr> readDir(const boost::filesystem::path &path) { + return std::unique_ptr>(readDir(path.c_str())); } - MOCK_METHOD1(readDir, std::vector*(const char*)); + MOCK_METHOD1(readDir, std::vector*(const char*)); void utimens(const boost::filesystem::path &path, const timespec ts[2]) override { return utimens(path.c_str(), ts); }