diff --git a/CMakeLists.txt b/CMakeLists.txt index be9fe3b..390ca87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,7 @@ if(NOT(WITHOUT_TEST)) test-src/integration/test_truncate.cpp test-src/integration/test_fsync.cpp test-src/integration/test_utimens.cpp + test-src/integration/test_open.cpp ) target_include_directories(integration_tests PRIVATE test-src/integration ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS}) diff --git a/src/webfuse/provider.cpp b/src/webfuse/provider.cpp index ae92eb7..e4a7dcd 100644 --- a/src/webfuse/provider.cpp +++ b/src/webfuse/provider.cpp @@ -88,6 +88,9 @@ public: case request_type::utimens: fs_utimens(reader, writer); break; + case request_type::open: + fs_open(reader, writer); + break; case request_type::create: fs_create(reader, writer); break; @@ -219,6 +222,20 @@ private: writer.write_i32(result); } + void fs_open(messagereader & reader, messagewriter & writer) + { + auto const path = reader.read_str(); + auto const flags = reader.read_openflags(); + uint64_t handle = static_cast(-1); + + auto const result = fs_.open(path, flags, handle); + writer.write_i32(result); + if (result == 0) + { + writer.write_u64(handle); + } + } + void fs_create(messagereader & reader, messagewriter & writer) { auto const path = reader.read_str(); diff --git a/src/webfuse/ws/messagereader.cpp b/src/webfuse/ws/messagereader.cpp index 1c22a85..1f966e3 100644 --- a/src/webfuse/ws/messagereader.cpp +++ b/src/webfuse/ws/messagereader.cpp @@ -2,6 +2,7 @@ #include "webfuse/filesystem/status.hpp" #include "webfuse/filesystem/filemode.hpp" #include "webfuse/filesystem/accessmode.hpp" +#include "webfuse/filesystem/openflags.hpp" #include @@ -186,5 +187,13 @@ void messagereader::read_time(struct timespec &time) time.tv_nsec = static_cast(read_u32()); } +int messagereader::read_openflags() +{ + auto const value = read_i32(); + openflags flags(value); + + return flags.to_int(); +} + } \ No newline at end of file diff --git a/src/webfuse/ws/messagereader.hpp b/src/webfuse/ws/messagereader.hpp index 22ad119..de4720c 100644 --- a/src/webfuse/ws/messagereader.hpp +++ b/src/webfuse/ws/messagereader.hpp @@ -41,7 +41,7 @@ public: void read_strings(std::vector &entries); void read_time(struct timespec &time); - + int read_openflags(); private: std::string data; diff --git a/test-src/integration/test_open.cpp b/test-src/integration/test_open.cpp new file mode 100644 index 0000000..dcfb3e9 --- /dev/null +++ b/test-src/integration/test_open.cpp @@ -0,0 +1,49 @@ +#include "webfuse/webfuse.hpp" +#include "webfuse/test/fixture.hpp" +#include "webfuse/test/filesystem_mock.hpp" + +#include +#include + +using testing::_; +using testing::Return; +using testing::Invoke; +using testing::AnyNumber; +using testing::AtMost; + +TEST(open, success) +{ + bool link_created = false; + + webfuse::filesystem_mock fs; + EXPECT_CALL(fs, access("/",_)).Times(AnyNumber()).WillRepeatedly(Return(0)); + EXPECT_CALL(fs, getattr(_,_)).WillRepeatedly(Invoke([&link_created](std::string const & path, struct stat * attr){ + memset(reinterpret_cast(attr),0, sizeof(struct stat)); + + if (path == "/") + { + attr->st_nlink = 1; + attr->st_mode = S_IFDIR | 0755; + return 0; + } + if (path == "/some_file") + { + attr->st_nlink = 1; + attr->st_mode = S_IFREG | 0755; + return 0; + } + else + { + return -ENOENT; + } + })); + EXPECT_CALL(fs, open("/some_file", O_RDONLY, _)).WillOnce(Return(0)); + EXPECT_CALL(fs, release("/some_file", _)).Times(AtMost(1)).WillOnce(Return(0)); + + webfuse::fixture fixture(fs); + auto const path = fixture.get_path() + "/some_file"; + + int fd = ::open(path.c_str(), O_RDONLY); + ASSERT_LT(0, fd); + ASSERT_EQ(0, ::close(fd)); +}