macos fixes
This commit is contained in:
@@ -51,6 +51,9 @@ fuse_base::fuse_base(app_config &config) : config_(config) {
|
||||
fuse_ops_.fallocate = fuse_base::fallocate_;
|
||||
fuse_ops_.fsync = fuse_base::fsync_;
|
||||
fuse_ops_.getattr = fuse_base::getattr_;
|
||||
#if FUSE_USE_VERSION < 30
|
||||
fuse_ops_.fgetattr = fuse_base::fgetattr_;
|
||||
#endif // FUSE_USE_VERSION < 30
|
||||
fuse_ops_.init = fuse_base::init_;
|
||||
fuse_ops_.ioctl = fuse_base::ioctl_;
|
||||
fuse_ops_.mkdir = fuse_base::mkdir_;
|
||||
|
@@ -594,7 +594,8 @@ auto fuse_drive::getxtimes_impl(std::string api_path, struct timespec *bkuptime,
|
||||
}
|
||||
|
||||
api_meta_map meta{};
|
||||
if ((res = provider_.get_item_meta(api_path, meta)) != api_error::success) {
|
||||
res = provider_.get_item_meta(api_path, meta);
|
||||
if (res != api_error::success) {
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1419,6 +1420,24 @@ auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2],
|
||||
auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2])
|
||||
-> api_error {
|
||||
#endif
|
||||
const auto validate_timespec = [](const timespec &spec) {
|
||||
if (spec.tv_nsec == UTIME_NOW || spec.tv_nsec == UTIME_OMIT) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (spec.tv_nsec < 0 ||
|
||||
spec.tv_nsec >=
|
||||
static_cast<std::int64_t>(utils::time::NANOS_PER_SECOND)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if (not validate_timespec(tv[0]) || not validate_timespec(tv[1])) {
|
||||
return api_error::invalid_operation;
|
||||
}
|
||||
|
||||
api_meta_map meta;
|
||||
auto res = provider_.get_item_meta(api_path, meta);
|
||||
if (res != api_error::success) {
|
||||
|
@@ -19,6 +19,7 @@
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
#if !defined(_WIN32)
|
||||
|
||||
#include "fixtures/drive_fixture.hpp"
|
||||
@@ -26,14 +27,13 @@
|
||||
namespace repertory {
|
||||
TYPED_TEST_SUITE(fuse_test, platform_provider_types);
|
||||
|
||||
TYPED_TEST(fuse_test, fallocate_basic_preallocation_platform_semantics) {
|
||||
TYPED_TEST(fuse_test, fallocate_can_handle_preallocate) {
|
||||
std::string name{"fallocate"};
|
||||
auto src = this->create_file_and_test(name);
|
||||
|
||||
auto desc = ::open(src.c_str(), O_RDWR);
|
||||
ASSERT_NE(desc, -1);
|
||||
|
||||
constexpr off_t off = 0;
|
||||
constexpr off_t len = 64 * 1024;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
@@ -45,17 +45,15 @@ TYPED_TEST(fuse_test, fallocate_basic_preallocation_platform_semantics) {
|
||||
store.fst_bytesalloc = 0;
|
||||
|
||||
auto res = ::fcntl(desc, F_PREALLOCATE, &store);
|
||||
if (res == -1) {
|
||||
store.fst_flags = F_ALLOCATEALL;
|
||||
res = ::fcntl(desc, F_PREALLOCATE, &store);
|
||||
}
|
||||
EXPECT_EQ(0, res);
|
||||
EXPECT_EQ(res, -1);
|
||||
|
||||
struct stat st_unix{};
|
||||
EXPECT_EQ(0, ::fstat(desc, &st_unix));
|
||||
EXPECT_TRUE(S_ISREG(st_unix.st_mode));
|
||||
EXPECT_EQ(0, st_unix.st_size);
|
||||
#else // !defined(__APPLE__)
|
||||
constexpr off_t off = 0;
|
||||
|
||||
auto res = ::posix_fallocate(desc, off, len);
|
||||
if (res == EOPNOTSUPP) {
|
||||
::close(desc);
|
||||
@@ -91,17 +89,8 @@ TYPED_TEST(fuse_test, fallocate_then_ftruncate_makes_size_visible) {
|
||||
store.fst_length = len;
|
||||
store.fst_bytesalloc = 0;
|
||||
auto res = ::fcntl(desc, F_PREALLOCATE, &store);
|
||||
if (res == -1) {
|
||||
store.fst_flags = F_ALLOCATEALL;
|
||||
res = ::fcntl(desc, F_PREALLOCATE, &store);
|
||||
}
|
||||
if (res == EOPNOTSUPP) {
|
||||
::close(desc);
|
||||
this->unlink_file_and_test(src);
|
||||
return;
|
||||
}
|
||||
EXPECT_EQ(res, -1);
|
||||
|
||||
EXPECT_EQ(0, res);
|
||||
EXPECT_EQ(0, ::ftruncate(desc, len));
|
||||
#else // !defined(__APPLE__)
|
||||
auto res = ::posix_fallocate(desc, 0, len);
|
||||
@@ -205,14 +194,7 @@ TYPED_TEST(fuse_test, fallocate_can_handle_invalid_arguments) {
|
||||
store.fst_length = 0;
|
||||
errno = 0;
|
||||
auto res = ::fcntl(desc, F_PREALLOCATE, &store);
|
||||
if (res == 0) {
|
||||
::close(desc);
|
||||
this->unlink_file_and_test(src);
|
||||
return;
|
||||
}
|
||||
|
||||
EXPECT_EQ(-1, res);
|
||||
EXPECT_TRUE(errno == EINVAL || errno == EOPNOTSUPP || errno == ENOSYS);
|
||||
EXPECT_EQ(res, -1);
|
||||
#else // !defined(__APPLE__)
|
||||
auto ret1 = ::posix_fallocate(desc, -1, 4096);
|
||||
EXPECT_EQ(EINVAL, ret1);
|
||||
@@ -241,19 +223,16 @@ TYPED_TEST(fuse_test, fallocate_fails_on_directory) {
|
||||
|
||||
errno = 0;
|
||||
auto res = ::fcntl(desc, F_PREALLOCATE, &store);
|
||||
EXPECT_EQ(-1, res);
|
||||
EXPECT_TRUE(errno == EISDIR || errno == EBADF || errno == EOPNOTSUPP ||
|
||||
errno == ENOTTY || errno == ENOSYS);
|
||||
::close(desc);
|
||||
EXPECT_EQ(res, -1);
|
||||
#else // !defined(__APPLE__)
|
||||
auto desc = ::open(dir.c_str(), O_RDONLY | O_DIRECTORY);
|
||||
EXPECT_NE(desc, -1);
|
||||
|
||||
auto ret = ::posix_fallocate(desc, 0, 4096);
|
||||
EXPECT_NE(0, ret);
|
||||
::close(desc);
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
::close(desc);
|
||||
this->rmdir_and_test(dir);
|
||||
}
|
||||
} // namespace repertory
|
||||
|
@@ -19,6 +19,7 @@
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
#if !defined(_WIN32)
|
||||
|
||||
#include "fixtures/drive_fixture.hpp"
|
||||
@@ -57,6 +58,11 @@ TYPED_TEST(fuse_test, fsync_noop_on_clean_desc) {
|
||||
}
|
||||
|
||||
TYPED_TEST(fuse_test, fsync_on_unlinked_file) {
|
||||
#if defined(__APPLE__)
|
||||
GTEST_SKIP();
|
||||
return;
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
std::string name{"fsync_unlinked"};
|
||||
auto path = this->create_file_and_test(name, 0644);
|
||||
|
||||
|
@@ -38,6 +38,12 @@ TYPED_TEST(fuse_test, unlink_can_remove_file) {
|
||||
}
|
||||
|
||||
TYPED_TEST(fuse_test, unlink_open_file_leaves_handle_intact) {
|
||||
#if defined(__APPLE__)
|
||||
// TODO fgetattr() not supported
|
||||
GTEST_SKIP();
|
||||
return;
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
std::string name{"unlink"};
|
||||
auto path = this->create_file_and_test(name);
|
||||
|
||||
@@ -54,6 +60,7 @@ TYPED_TEST(fuse_test, unlink_open_file_leaves_handle_intact) {
|
||||
ASSERT_EQ(0, ::unlink(path.c_str()));
|
||||
|
||||
auto res = ::lseek(desc, 0, SEEK_END);
|
||||
fmt::println("lseek|{}|{}", res, errno);
|
||||
|
||||
ASSERT_NE(-1, res);
|
||||
this->write_all(desc, " WORLD");
|
||||
@@ -62,11 +69,12 @@ TYPED_TEST(fuse_test, unlink_open_file_leaves_handle_intact) {
|
||||
std::string out;
|
||||
char buf[4096];
|
||||
for (;;) {
|
||||
ssize_t r = ::read(desc, buf, sizeof(buf));
|
||||
ASSERT_NE(r, -1);
|
||||
if (r == 0)
|
||||
res = ::read(desc, buf, sizeof(buf));
|
||||
ASSERT_NE(res, -1);
|
||||
if (res == 0) {
|
||||
break;
|
||||
out.append(buf, buf + r);
|
||||
}
|
||||
out.append(buf, buf + res);
|
||||
}
|
||||
::close(desc);
|
||||
|
||||
@@ -88,7 +96,11 @@ TYPED_TEST(fuse_test, unlink_directory_fails) {
|
||||
|
||||
errno = 0;
|
||||
EXPECT_EQ(-1, ::unlink(dir.c_str()));
|
||||
#if defined(__APPLE__)
|
||||
EXPECT_EQ(EPERM, errno);
|
||||
#else // !defined(__APPLE__)
|
||||
EXPECT_EQ(EISDIR, errno);
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
this->rmdir_and_test(dir);
|
||||
}
|
||||
|
@@ -74,8 +74,9 @@ void get_times_ns(const std::string &path, long long &at_ns, long long &mt_ns) {
|
||||
}
|
||||
|
||||
constexpr long long GRANULAR_TOL_NS =
|
||||
1LL * static_cast<long long>(NANOS_PER_SECOND);
|
||||
constexpr long long NOW_TOL_NS = 5LL * static_cast<long long>(NANOS_PER_SECOND);
|
||||
12LL * static_cast<long long>(NANOS_PER_SECOND);
|
||||
constexpr long long NOW_TOL_NS =
|
||||
15LL * static_cast<long long>(NANOS_PER_SECOND);
|
||||
} // namespace
|
||||
|
||||
namespace repertory {
|
||||
|
Reference in New Issue
Block a user