diff --git a/repertory/repertory_test/src/fuse_drive_directory_test.cpp b/repertory/repertory_test/src/fuse_drive_directory_test.cpp index a9f3093c..aac7620a 100644 --- a/repertory/repertory_test/src/fuse_drive_directory_test.cpp +++ b/repertory/repertory_test/src/fuse_drive_directory_test.cpp @@ -138,6 +138,89 @@ TYPED_TEST(fuse_test, directory_rmdir_on_non_empty_directory_should_fail) { this->rmdir_and_test(dir); this->rmdir_and_test(dir2); } + +TYPED_TEST(fuse_test, + directory_rmdir_open_directory_handle_then_readdir_and_closedir) { + std::string dname{"rm_opendir"}; + auto dir = this->create_directory_and_test(dname); + + auto *dir_ptr = ::opendir(dir.c_str()); + ASSERT_NE(dir_ptr, nullptr); + + errno = 0; + auto res = ::rmdir(dir.c_str()); + if (res == -1 && errno == EBUSY) { + ::closedir(dir_ptr); + GTEST_SKIP(); + } + ASSERT_EQ(0, res); + + struct stat u_stat{}; + EXPECT_EQ(-1, ::stat(dir.c_str(), &u_stat)); + EXPECT_EQ(ENOENT, errno); + + ::rewinddir(dir_ptr); + + errno = 0; + auto *dir_entry = ::readdir(dir_ptr); + EXPECT_EQ(nullptr, dir_entry); + ::closedir(dir_ptr); +} + +TYPED_TEST(fuse_test, + directory_rmdir_open_directory_handle_non_empty_ENOTEMPTY) { + std::string dname{"rm_opendir_ne"}; + auto dir = this->create_directory_and_test(dname); + + std::string child{dname + "/child"}; + auto child_path = this->create_file_and_test(child, 0644); + this->overwrite_text(child_path, "x"); + + auto *dir_ptr = ::opendir(dir.c_str()); + ASSERT_NE(dir_ptr, nullptr); + + errno = 0; + EXPECT_EQ(-1, ::rmdir(dir.c_str())); + EXPECT_EQ(ENOTEMPTY, errno); + + ::rewinddir(dir_ptr); + [[maybe_unused]] auto *dir_ptr2 = ::readdir(dir_ptr); + ::closedir(dir_ptr); + + this->unlink_file_and_test(child_path); + this->rmdir_and_test(dir); +} + +// TODO implement POSIX-compliant rmdir when handle is open +// TYPED_TEST(fuse_test, directory_rmdir_open_directory_handle_fstat_dirfd_ok) { +// std::string dname{"rm_opendir_fstat"}; +// auto dir = this->create_directory_and_test(dname); +// +// auto *dir_ptr = ::opendir(dir.c_str()); +// ASSERT_NE(dir_ptr, nullptr); +// auto dfd = ::dirfd(dir_ptr); +// ASSERT_NE(dfd, -1); +// +// struct stat before{}; +// ASSERT_EQ(0, ::fstat(dfd, &before)); +// +// errno = 0; +// auto res = ::rmdir(dir.c_str()); +// if (res == -1 && errno == EBUSY) { +// ::closedir(dir_ptr); +// GTEST_SKIP(); +// } +// ASSERT_EQ(0, res); +// +// struct stat after{}; +// ASSERT_EQ(0, ::fstat(dfd, &after)); +// +// ::closedir(dir_ptr); +// +// struct stat u_stat{}; +// EXPECT_EQ(-1, ::stat(dir.c_str(), &u_stat)); +// EXPECT_EQ(ENOENT, errno); +// } } // namespace repertory #endif // !defined(_WIN32)