diff --git a/src/fspp/fuse/Fuse.cpp b/src/fspp/fuse/Fuse.cpp index acefd29d..572d97e8 100644 --- a/src/fspp/fuse/Fuse.cpp +++ b/src/fspp/fuse/Fuse.cpp @@ -234,29 +234,37 @@ void Fuse::run(const bf::path &mountdir, const vector &fuseOptions) { ASSERT(_argv.size() == 0, "Filesystem already started"); - _argv.reserve(2 + fuseOptions.size()); - _argv.push_back(_create_c_string(_fstype)); // The first argument is the file system name + _argv = _build_argv(mountdir, fuseOptions); + + fuse_main(_argv.size(), _argv.data(), operations(), (void*)this); +} + +vector Fuse::_build_argv(const bf::path &mountdir, const vector &fuseOptions) { + vector argv; + _argv.reserve(6 + fuseOptions.size()); // fuseOptions + executable name + mountdir + 2x fuse options (subtype, fsname), each taking 2 entries ("-o", "key=value"). + _argv.push_back(_create_c_string(_fstype)); // The first argument (executable name) is the file system type _argv.push_back(_create_c_string(mountdir.native())); // The second argument is the mountdir for (const string &option : fuseOptions) { _argv.push_back(_create_c_string(option)); } - if(_fsname != boost::none) { - auto hasNoOption = [&](const char *opt) { - for (const string& it : fuseOptions) { - if (std::strncmp(it.c_str(), opt, std::strlen(opt))) { - return false; - } - } - return true; - }; - if (hasNoOption("subtype=") && hasNoOption("fsname=")) { - _argv.push_back(_create_c_string("-o")); - _argv.push_back(_create_c_string("fsname="+*_fsname)); - _argv.push_back(_create_c_string("-o")); - _argv.push_back(_create_c_string("subtype="+_fstype)); - } + _add_fuse_option_if_not_exists(&_argv, "subtype", _fstype); + _add_fuse_option_if_not_exists(&_argv, "fsname", _fsname.get_value_or(_fstype)); + return argv; +} + +void Fuse::_add_fuse_option_if_not_exists(vector *argv, const string &key, const string &value) { + if(!_has_option(*argv, key)) { + argv->push_back(_create_c_string("-o")); + argv->push_back(_create_c_string(key + "=" + value)); } - fuse_main(_argv.size(), _argv.data(), operations(), (void*)this); +} + +bool Fuse::_has_option(const vector &vec, const string &key) { + string key_with_prefix = key + "+"; + auto found = std::find_if(vec.begin(), vec.end(), [&key_with_prefix](const char *entry) { + return std::strncmp(key_with_prefix.c_str(), entry, key_with_prefix.size()); + }); + return found != vec.end(); } char *Fuse::_create_c_string(const string &str) { diff --git a/src/fspp/fuse/Fuse.h b/src/fspp/fuse/Fuse.h index 0bb3c273..005b7071 100644 --- a/src/fspp/fuse/Fuse.h +++ b/src/fspp/fuse/Fuse.h @@ -61,6 +61,9 @@ private: static void _logException(const std::exception &e); static void _logUnknownException(); static char *_create_c_string(const std::string &str); + static bool _has_option(const std::vector &vec, const std::string &key); + std::vector _build_argv(const boost::filesystem::path &mountdir, const std::vector &fuseOptions); + void _add_fuse_option_if_not_exists(std::vector *argv, const std::string &key, const std::string &value); Filesystem *_fs; boost::filesystem::path _mountdir; diff --git a/test/fspp/testutils/FuseTest.cpp b/test/fspp/testutils/FuseTest.cpp index 651b1c18..491d355f 100644 --- a/test/fspp/testutils/FuseTest.cpp +++ b/test/fspp/testutils/FuseTest.cpp @@ -53,7 +53,7 @@ unique_ref FuseTest::TestFS() { return make_unique_ref(&fsimpl); } -FuseTest::TempTestFS::TempTestFS(MockFilesystem *fsimpl): _mountDir(), _fuse(fsimpl), _fuse_thread(&_fuse) { +FuseTest::TempTestFS::TempTestFS(MockFilesystem *fsimpl): _mountDir(), _fuse(fsimpl, "fusetest", boost::none), _fuse_thread(&_fuse) { _fuse_thread.start(_mountDir.path(), {"-f"}); }