Browse Source

Move everything to negative errno return types (#1499)

pull/1500/head
trapexit 3 months ago
committed by GitHub
parent
commit
e8cd74cab0
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      LICENSE
  2. 33
      src/error.hpp
  3. 24
      src/fs_acl.cpp
  4. 12
      src/fs_attr_linux.icpp
  5. 30
      src/fs_attr_unsupported.icpp
  6. 225
      src/fs_clonepath.cpp
  7. 24
      src/fs_clonepath.hpp
  8. 22
      src/fs_close.hpp
  9. 22
      src/fs_closedir.hpp
  10. 102
      src/fs_copy_file_range_linux.icpp
  11. 41
      src/fs_copy_file_range_unsupported.icpp
  12. 47
      src/fs_copydata.cpp
  13. 31
      src/fs_copydata_copy_file_range.cpp
  14. 41
      src/fs_copydata_readwrite.cpp
  15. 40
      src/fs_copyfile.cpp
  16. 2
      src/fs_cow.cpp
  17. 2
      src/fs_devid.hpp
  18. 8
      src/fs_dirfd.hpp
  19. 8
      src/fs_dup.hpp
  20. 4
      src/fs_dup2.hpp
  21. 8
      src/fs_faccessat.hpp
  22. 9
      src/fs_fadvise_posix.icpp
  23. 4
      src/fs_fadvise_unsupported.icpp
  24. 10
      src/fs_fallocate_linux.icpp
  25. 68
      src/fs_fallocate_osx.icpp
  26. 11
      src/fs_fallocate_posix.icpp
  27. 4
      src/fs_fallocate_unsupported.icpp
  28. 21
      src/fs_fchmod.hpp
  29. 10
      src/fs_fchmodat.hpp
  30. 18
      src/fs_fchown.hpp
  31. 25
      src/fs_fcntl.hpp
  32. 10
      src/fs_fdatasync.hpp
  33. 16
      src/fs_fgetxattr.hpp
  34. 2
      src/fs_ficlone_unsupported.icpp
  35. 2
      src/fs_file_size.cpp
  36. 18
      src/fs_file_unchanged.hpp
  37. 35
      src/fs_findallfiles.cpp
  38. 87
      src/fs_findonfs.cpp
  39. 10
      src/fs_flistxattr.hpp
  40. 8
      src/fs_flock.hpp
  41. 10
      src/fs_fsetxattr.hpp
  42. 5
      src/fs_fstat.hpp
  43. 7
      src/fs_fstatat.hpp
  44. 40
      src/fs_fstatvfs.hpp
  45. 8
      src/fs_fsync.hpp
  46. 9
      src/fs_ftruncate.hpp
  47. 8
      src/fs_futimens_freebsd_11.hpp
  48. 381
      src/fs_futimens_generic.hpp
  49. 8
      src/fs_futimens_linux.hpp
  50. 8
      src/fs_futimesat_generic.icpp
  51. 32
      src/fs_futimesat_osx.icpp
  52. 16
      src/fs_getdents64.cpp
  53. 6
      src/fs_getdents64.hpp
  54. 4
      src/fs_getfl.cpp
  55. 25
      src/fs_glob.cpp
  56. 27
      src/fs_has_space.cpp
  57. 35
      src/fs_info.cpp
  58. 246
      src/fs_inode.cpp
  59. 8
      src/fs_ioctl.hpp
  60. 3
      src/fs_is_rofs.hpp
  61. 31
      src/fs_lchmod.hpp
  62. 19
      src/fs_lchown.hpp
  63. 16
      src/fs_lgetxattr.hpp
  64. 10
      src/fs_link.hpp
  65. 4
      src/fs_llistxattr.hpp
  66. 10
      src/fs_lremovexattr.hpp
  67. 8
      src/fs_lseek.hpp
  68. 18
      src/fs_lsetxattr.hpp
  69. 8
      src/fs_lstat.hpp
  70. 55
      src/fs_lstatvfs.hpp
  71. 8
      src/fs_mkdir.hpp
  72. 19
      src/fs_mknod.hpp
  73. 133
      src/fs_mktemp.cpp
  74. 6
      src/fs_mounts.cpp
  75. 16
      src/fs_movefile_and_open.cpp
  76. 14
      src/fs_open.hpp
  77. 5
      src/fs_openat.hpp
  78. 10
      src/fs_opendir.hpp
  79. 50
      src/fs_path.cpp
  80. 2
      src/fs_path.hpp
  81. 4
      src/fs_pread.hpp
  82. 6
      src/fs_pwrite.hpp
  83. 17
      src/fs_read.hpp
  84. 20
      src/fs_readahead.cpp
  85. 10
      src/fs_readlink.hpp
  86. 32
      src/fs_realpathize.cpp
  87. 8
      src/fs_remove.hpp
  88. 8
      src/fs_rename.hpp
  89. 8
      src/fs_rmdir.hpp
  90. 7
      src/fs_sendfile_linux.icpp
  91. 15
      src/fs_sendfile_unsupported.icpp
  92. 15
      src/fs_setfl.cpp
  93. 8
      src/fs_stat.hpp
  94. 44
      src/fs_statvfs.hpp
  95. 184
      src/fs_statvfs_cache.cpp
  96. 2
      src/fs_statvfs_cache.hpp
  97. 4
      src/fs_statx.hpp
  98. 14
      src/fs_symlink.hpp
  99. 8
      src/fs_truncate.hpp
  100. 7
      src/fs_umount2.hpp

2
LICENSE

@ -1,7 +1,7 @@
/*
ISC License
Copyright (c) 2024, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2025, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above

33
src/error.hpp

@ -0,0 +1,33 @@
#pragma once
#include "errno.hpp"
#include <optional>
struct Err
{
private:
std::optional<int> _err;
public:
Err()
{
}
operator int()
{
return (_err.has_value() ? _err.value() : -ENOENT);
}
Err&
operator=(int v_)
{
if(!_err.has_value())
_err = v_;
else if(v_ >= 0)
_err = v_;
return *this;
}
};

24
src/fs_acl.cpp

@ -16,29 +16,25 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_acl.hpp"
#include "fs_lgetxattr.hpp"
#include "fs_path.hpp"
#include <string>
const char POSIX_ACL_DEFAULT_XATTR[] = "system.posix_acl_default";
constexpr const char POSIX_ACL_DEFAULT_XATTR[] = "system.posix_acl_default";
namespace fs
bool
fs::acl::dir_has_defaults(const std::string &fullpath_)
{
namespace acl
{
bool
dir_has_defaults(const std::string &fullpath_)
{
int rv;
std::string dirpath;
int rv;
std::string dirpath;
dirpath = fs::path::dirname(fullpath_);
dirpath = fs::path::dirname(fullpath_);
rv = fs::lgetxattr(dirpath,POSIX_ACL_DEFAULT_XATTR,NULL,0);
rv = fs::lgetxattr(dirpath,POSIX_ACL_DEFAULT_XATTR,NULL,0);
return (rv != -1);
}
}
return (rv >= 0);
}

12
src/fs_attr_linux.icpp

@ -37,7 +37,7 @@ _get_fs_ioc_flags(const int fd,
rv = fs::ioctl(fd,FS_IOC_GETFLAGS,(void*)&flags);
if(rv == -EINVAL)
rv = ENOTSUP;
rv = -ENOTSUP;
return rv;
}
@ -52,8 +52,8 @@ _get_fs_ioc_flags(const string &file,
const int openflags = O_RDONLY|O_NONBLOCK;
fd = fs::open(file,openflags);
if(fd == -1)
return -errno;
if(fd < 0)
return fd;
rv = ::_get_fs_ioc_flags(fd,flags);
if(rv < 0)
@ -74,7 +74,7 @@ _set_fs_ioc_flags(const int fd,
rv = fs::ioctl(fd,FS_IOC_SETFLAGS,(void*)&flags);
if(rv == -EINVAL)
rv = ENOTSUP;
rv = -ENOTSUP;
return rv;
}
@ -89,8 +89,8 @@ _set_fs_ioc_flags(const string &file,
const int openflags = O_RDONLY|O_NONBLOCK;
fd = fs::open(file,openflags);
if(fd == -1)
return -errno;
if(fd < 0)
return fd;
rv = ::_set_fs_ioc_flags(fd,flags);
if(rv < 0)

30
src/fs_attr_unsupported.icpp

@ -14,27 +14,21 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_attr.hpp"
#include <string>
#include "errno.hpp"
namespace fs
int
fs::attr::copy(const int fdin,
const int fdout)
{
namespace attr
{
int
copy(const int fdin,
const int fdout)
{
return (errno=ENOTSUP,-1);
}
return -ENOTSUP;
}
int
copy(const std::string &from,
const std::string &to)
{
return (errno=ENOTSUP,-1);
}
}
int
fs::attr::copy(const std::string &from,
const std::string &to)
{
return -ENOTSUP;
}

225
src/fs_clonepath.cpp

@ -14,6 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_clonepath.hpp"
#include "errno.h"
#include "fs_attr.hpp"
#include "fs_clonepath.hpp"
@ -30,131 +32,124 @@
using std::string;
namespace l
static
bool
_ignorable_error(const int err_)
{
static
bool
ignorable_error(const int err_)
{
switch(err_)
{
case ENOTTY:
case ENOTSUP:
switch(err_)
{
case ENOTTY:
case ENOTSUP:
#if ENOTSUP != EOPNOTSUPP
case EOPNOTSUPP:
case EOPNOTSUPP:
#endif
return true;
}
return true;
}
return false;
}
return false;
}
namespace fs
/*
Attempts to clone a path.
The directories which already exist are left alone.
The new directories have metadata set to match the original if
possible. Optionally ignore errors on metadata copies.
*/
int
fs::clonepath(const string &srcpath_,
const string &dstpath_,
const char *relpath_,
const bool return_metadata_errors_)
{
/*
Attempts to clone a path.
The directories which already exist are left alone.
The new directories have metadata set to match the original if
possible. Optionally ignore errors on metadata copies.
*/
int
clonepath(const string &fromsrc_,
const string &tosrc_,
const char *relative_,
const bool return_metadata_errors_)
{
int rv;
struct stat st;
string topath;
string frompath;
string dirname;
if((relative_ == NULL) || (relative_[0] == '\0'))
return 0;
dirname = fs::path::dirname(relative_);
if(dirname != "/")
{
rv = fs::clonepath(fromsrc_,tosrc_,dirname,return_metadata_errors_);
if(rv == -1)
return -1;
}
frompath = fs::path::make(fromsrc_,relative_);
rv = fs::lstat(frompath,&st);
if(rv == -1)
return -1;
else if(!S_ISDIR(st.st_mode))
return (errno=ENOTDIR,-1);
topath = fs::path::make(tosrc_,relative_);
rv = fs::mkdir(topath,st.st_mode);
if(rv == -1)
{
if(errno == EEXIST)
return 0;
else
return -1;
}
// it may not support it... it's fine...
rv = fs::attr::copy(frompath,topath);
if(return_metadata_errors_ && (rv < 0) && !l::ignorable_error(-rv))
return -1;
// it may not support it... it's fine...
rv = fs::xattr::copy(frompath,topath);
if(return_metadata_errors_ && (rv == -1) && !l::ignorable_error(errno))
return -1;
rv = fs::lchown_check_on_error(topath,st);
if(return_metadata_errors_ && (rv == -1))
return -1;
rv = fs::lutimens(topath,st);
if(return_metadata_errors_ && (rv == -1))
return -1;
int rv;
struct stat st;
string dstpath;
string srcpath;
string dirname;
if((relpath_ == NULL) || (relpath_[0] == '\0'))
return 0;
}
int
clonepath(const string &from_,
const string &to_,
const string &relative_,
const bool return_metadata_errors_)
{
return fs::clonepath(from_,
to_,
relative_.c_str(),
return_metadata_errors_);
}
int
clonepath_as_root(const string &from_,
const string &to_,
const char *relative_,
const bool return_metadata_errors_)
{
if((relative_ == NULL) || (relative_[0] == '\0'))
return 0;
if(from_ == to_)
return 0;
dirname = fs::path::dirname(relpath_);
if(dirname != "/")
{
const ugid::SetRootGuard ugidGuard;
return fs::clonepath(from_,to_,relative_,return_metadata_errors_);
rv = fs::clonepath(srcpath_,dstpath_,dirname,return_metadata_errors_);
if(rv < 0)
return rv;
}
}
int
clonepath_as_root(const string &from_,
const string &to_,
const string &relative_,
const bool return_metadata_errors_)
{
return fs::clonepath_as_root(from_,to_,relative_.c_str(),return_metadata_errors_);
}
srcpath = fs::path::make(srcpath_,relpath_);
rv = fs::lstat(srcpath,&st);
if(rv < 0)
return rv;
else if(!S_ISDIR(st.st_mode))
return -ENOTDIR;
dstpath = fs::path::make(dstpath_,relpath_);
rv = fs::mkdir(dstpath,st.st_mode);
if(rv < 0)
return ((rv == -EEXIST) ? 0 : rv);
// it may not support it... it's fine...
rv = fs::attr::copy(srcpath,dstpath);
if(return_metadata_errors_ && (rv < 0) && !::_ignorable_error(-rv))
return rv;
// it may not support it... it's fine...
rv = fs::xattr::copy(srcpath,dstpath);
if(return_metadata_errors_ && (rv < 0) && !::_ignorable_error(-rv))
return rv;
rv = fs::lchown_check_on_error(dstpath,st);
if(return_metadata_errors_ && (rv < 0))
return rv;
rv = fs::lutimens(dstpath,st);
if(return_metadata_errors_ && (rv < 0))
return rv;
return 0;
}
int
fs::clonepath(const string &srcpath_,
const string &dstpath_,
const string &relpath_,
const bool return_metadata_errors_)
{
return fs::clonepath(srcpath_,
dstpath_,
relpath_.c_str(),
return_metadata_errors_);
}
int
fs::clonepath_as_root(const string &srcpath_,
const string &dstpath_,
const char *relpath_,
const bool return_metadata_errors_)
{
if((relpath_ == NULL) || (relpath_[0] == '\0'))
return 0;
if(srcpath_ == dstpath_)
return 0;
const ugid::SetRootGuard ugid_guard;
return fs::clonepath(srcpath_,
dstpath_,
relpath_,
return_metadata_errors_);
}
int
fs::clonepath_as_root(const string &srcpath_,
const string &dstpath_,
const string &relpath_,
const bool return_metadata_errors_)
{
return fs::clonepath_as_root(srcpath_,
dstpath_,
relpath_.c_str(),
return_metadata_errors_);
}

24
src/fs_clonepath.hpp

@ -21,21 +21,21 @@
namespace fs
{
int clonepath(const std::string &from,
const std::string &to,
const char *relative,
int clonepath(const std::string &srcpath,
const std::string &dstpath,
const char *relpath,
const bool return_metadata_errors = false);
int clonepath(const std::string &from,
const std::string &to,
const std::string &relative,
int clonepath(const std::string &srcpath,
const std::string &dstpath,
const std::string &relpath,
const bool return_metadata_errors = false);
int clonepath_as_root(const std::string &from,
const std::string &to,
const char *relative,
int clonepath_as_root(const std::string &srcpath,
const std::string &dstpath,
const char *relpath,
const bool return_metadata_errors = false);
int clonepath_as_root(const std::string &from,
const std::string &to,
const std::string &relative,
int clonepath_as_root(const std::string &srcpath,
const std::string &dstpath,
const std::string &relpath,
const bool return_metadata_errors = false);
}

22
src/fs_close.hpp

@ -18,16 +18,24 @@
#pragma once
#include "to_neg_errno.hpp"
#include <unistd.h>
namespace fs
{
static
inline
int
close(const int fd_)
{
return ::close(fd_);
}
static inline int close(const int fd);
}
static
inline
int
fs::close(const int fd_)
{
int rv;
rv = ::close(fd_);
return ::to_neg_errno(rv);
}

22
src/fs_closedir.hpp

@ -18,17 +18,25 @@
#pragma once
#include "to_neg_errno.hpp"
#include <dirent.h>
#include <sys/types.h>
namespace fs
{
static
inline
int
closedir(DIR *dirp_)
{
return ::closedir(dirp_);
}
static inline int closedir(DIR *dirp);
}
static
inline
int
fs::closedir(DIR *dirp_)
{
int rv;
rv = ::closedir(dirp_);
return ::to_neg_errno(rv);
}

102
src/fs_copy_file_range_linux.icpp

@ -16,11 +16,13 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_copy_file_range.hpp"
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include "errno.hpp"
#include "to_neg_errno.hpp"
#include <cstdint>
@ -31,66 +33,60 @@
#include <unistd.h>
namespace l
static
int64_t
_copy_file_range_(int src_fd_,
int64_t *src_off_,
int tgt_fd_,
int64_t *tgt_off_,
const uint64_t len_,
const unsigned int flags_)
{
static
int64_t
copy_file_range_(int src_fd_,
int64_t *src_off_,
int tgt_fd_,
int64_t *tgt_off_,
const uint64_t len_,
const unsigned int flags_)
{
#ifdef SYS_copy_file_range
int64_t rv;
loff_t src_off;
loff_t tgt_off;
loff_t *src_off_ptr;
loff_t *tgt_off_ptr;
int64_t rv;
loff_t src_off;
loff_t tgt_off;
loff_t *src_off_ptr;
loff_t *tgt_off_ptr;
src_off = ((src_off_ == NULL) ? 0 : *src_off_);
tgt_off = ((tgt_off_ == NULL) ? 0 : *tgt_off_);
src_off_ptr = ((src_off_ == NULL) ? NULL : &src_off);
tgt_off_ptr = ((tgt_off_ == NULL) ? NULL : &tgt_off);
rv = ::syscall(SYS_copy_file_range,
src_fd_,
src_off_ptr,
tgt_fd_,
tgt_off_ptr,
len_,
flags_);
src_off = ((src_off_ == NULL) ? 0 : *src_off_);
tgt_off = ((tgt_off_ == NULL) ? 0 : *tgt_off_);
src_off_ptr = ((src_off_ == NULL) ? NULL : &src_off);
tgt_off_ptr = ((tgt_off_ == NULL) ? NULL : &tgt_off);
rv = ::syscall(SYS_copy_file_range,
src_fd_,
src_off_ptr,
tgt_fd_,
tgt_off_ptr,
len_,
flags_);
if(rv != -1)
{
if(src_off_ != NULL)
*src_off_ = src_off;
if(tgt_off_ != NULL)
*tgt_off_ = tgt_off;
}
if(rv != -1)
{
if(src_off_ != NULL)
*src_off_ = src_off;
if(tgt_off_ != NULL)
*tgt_off_ = tgt_off;
}
return rv;
return ::to_neg_errno(rv);
#else
return (errno=EOPNOTSUPP,-1);
return -EOPNOTSUPP;
#endif
}
}
namespace fs
int64_t
fs::copy_file_range(const int src_fd_,
int64_t *src_off_,
const int tgt_fd_,
int64_t *tgt_off_,
const uint64_t len_,
const unsigned int flags_)
{
int64_t
copy_file_range(const int src_fd_,
int64_t *src_off_,
const int tgt_fd_,
int64_t *tgt_off_,
const uint64_t len_,
const unsigned int flags_)
{
return l::copy_file_range_(src_fd_,
src_off_,
tgt_fd_,
tgt_off_,
len_,
flags_);
}
return ::_copy_file_range_(src_fd_,
src_off_,
tgt_fd_,
tgt_off_,
len_,
flags_);
}

41
src/fs_copy_file_range_unsupported.icpp

@ -16,7 +16,9 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.h"
#include "fs_copy_file_range.hpp"
#include "errno.hpp"
#include <cstdint>
@ -24,25 +26,22 @@
#include <sys/types.h>
namespace fs
ssize_t
fs::copy_file_range(const int fd_in_,
int64_t *off_in_,
const int fd_out_,
int64_t *off_out_,
const size_t len_,
const unsigned int flags_)
{
return -EOPNOTSUPP;
}
ssize_t
fs::copy_file_range(const int fd_in_,
const int fd_out_,
const size_t len_,
const unsigned int flags_)
{
ssize_t
copy_file_range(const int fd_in_,
int64_t *off_in_,
const int fd_out_,
int64_t *off_out_,
const size_t len_,
const unsigned int flags_)
{
return (errno=EOPNOTSUPP,-1);
}
ssize_t
copy_file_range(const int fd_in_,
const int fd_out_,
const size_t len_,
const unsigned int flags_)
{
return (errno=EOPNOTSUPP,-1);
}
return -EOPNOTSUPP;
}

47
src/fs_copydata.cpp

@ -16,40 +16,33 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_copydata.hpp"
#include "fs_copydata_copy_file_range.hpp"
#include "fs_copydata_readwrite.hpp"
#include "fs_fadvise.hpp"
#include "fs_fallocate.hpp"
#include "fs_ficlone.hpp"
#include <stddef.h>
namespace fs
int
fs::copydata(const int src_fd_,
const int dst_fd_,
const size_t count_)
{
int
copydata(const int src_fd_,
const int dst_fd_,
const size_t count_)
{
int rv;
rv = fs::fallocate(dst_fd_,0,0,count_);
if((rv == -1) && (errno == ENOSPC))
return rv;
rv = fs::ficlone(src_fd_,dst_fd_);
if(rv != -1)
return rv;
fs::fadvise_willneed(src_fd_,0,count_);
fs::fadvise_sequential(src_fd_,0,count_);
rv = fs::copydata_copy_file_range(src_fd_,dst_fd_,count_);
if(rv != -1)
return rv;
return fs::copydata_readwrite(src_fd_,dst_fd_,count_);
}
int rv;
rv = fs::ficlone(src_fd_,dst_fd_);
if(rv >= 0)
return rv;
fs::fadvise_willneed(src_fd_,0,count_);
fs::fadvise_sequential(src_fd_,0,count_);
rv = fs::copydata_copy_file_range(src_fd_,dst_fd_,count_);
if(rv >= 0)
return rv;
return fs::copydata_readwrite(src_fd_,dst_fd_,count_);
}

31
src/fs_copydata_copy_file_range.cpp

@ -14,6 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_copydata_copy_file_range.hpp"
#include "errno.hpp"
#include "fs_copy_file_range.hpp"
#include "fs_fstat.hpp"
@ -38,29 +40,28 @@ _copydata_copy_file_range(const int src_fd_,
do
{
rv = fs::copy_file_range(src_fd_,&src_off,dst_fd_,&dst_off,nleft,0);
if((rv == -1) && (errno == EINTR))
if(rv == -EINTR)
continue;
if((rv == -1) && (errno == EAGAIN))
if(rv == -EAGAIN)
continue;
if(rv == -1)
return -1;
if(rv == 0)
break;
if(rv < 0)
return rv;
nleft -= rv;
}
while(nleft > 0);
return size_;
return (size_ - nleft);
}
namespace fs
s64
fs::copydata_copy_file_range(const int src_fd_,
const int dst_fd_,
const u64 count_)
{
s64
copydata_copy_file_range(const int src_fd_,
const int dst_fd_,
const u64 count_)
{
return ::_copydata_copy_file_range(src_fd_,
dst_fd_,
count_);
}
return ::_copydata_copy_file_range(src_fd_,
dst_fd_,
count_);
}

41
src/fs_copydata_readwrite.cpp

@ -38,19 +38,21 @@ _writen(const int fd_,
do
{
rv = fs::write(fd_,buf_,nleft);
if((rv == -1) && (errno == EINTR))
if(rv == -EINTR)
continue;
if((rv == -1) && (errno == EAGAIN))
if(rv == -EAGAIN)
continue;
if(rv == -1)
return -1;
if(rv == 0)
break;
if(rv < 0)
return rv;
nleft -= rv;
buf_ += rv;
}
while(nleft > 0);
return size_;
return (size_ - nleft);
}
static
@ -74,16 +76,16 @@ _copydata_readwrite(const int src_fd_,
nr = fs::read(src_fd_,&buf[0],bufsize);
if(nr == 0)
return totalwritten;
if((nr == -1) && (errno == EINTR))
if(nr == -EINTR)
continue;
if((nr == -1) && (errno == EAGAIN))
if(nr == -EAGAIN)
continue;
if(nr == -1)
return -1;
if(nr < 0)
return nr;
nw = ::_writen(dst_fd_,&buf[0],nr);
if(nw == -1)
return -1;
if(nw < 0)
return nw;
totalwritten += nw;
}
@ -92,15 +94,12 @@ _copydata_readwrite(const int src_fd_,
}
namespace fs
s64
fs::copydata_readwrite(const int src_fd_,
const int dst_fd_,
const u64 count_)
{
s64
copydata_readwrite(const int src_fd_,
const int dst_fd_,
const u64 count_)
{
return ::_copydata_readwrite(src_fd_,
dst_fd_,
count_);
}
return ::_copydata_readwrite(src_fd_,
dst_fd_,
count_);
}

40
src/fs_copyfile.cpp

@ -1,3 +1,21 @@
/*
ISC License
Copyright (c) 2025, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_copyfile.hpp"
#include "fs_attr.hpp"
@ -46,28 +64,28 @@ fs::copyfile(const int src_fd_,
int rv;
rv = fs::copydata(src_fd_,dst_fd_,src_st_.st_size);
if(rv == -1)
return -1;
if(rv < 0)
return rv;
rv = fs::xattr::copy(src_fd_,dst_fd_);
if((rv == -1) && !::_ignorable_error(errno))
return -1;
if((rv < 0) && !::_ignorable_error(-rv))
return rv;
rv = fs::attr::copy(src_fd_,dst_fd_,FS_ATTR_CLEAR_IMMUTABLE);
if((rv < 0) && !::_ignorable_error(-rv))
return -1;
return rv;
rv = fs::fchown_check_on_error(dst_fd_,src_st_);
if(rv == -1)
return -1;
if(rv < 0)
return rv;
rv = fs::fchmod_check_on_error(dst_fd_,src_st_);
if(rv == -1)
return -1;
if(rv < 0)
return rv;
rv = fs::futimens(dst_fd_,src_st_);
if(rv == -1)
return -1;
if(rv < 0)
return rv;
return 0;
}

2
src/fs_cow.cpp

@ -63,7 +63,7 @@ fs::cow::is_eligible(const char *fullpath_,
return false;
rv = fs::lstat(fullpath_,&st);
if(rv == -1)
if(rv < 0)
return false;
return fs::cow::is_eligible(st);

2
src/fs_devid.hpp

@ -34,7 +34,7 @@ namespace fs
rv = fs::fstat(fd_,&st);
if(rv < 0)
return -1;
return rv;
return st.st_dev;
}

8
src/fs_dirfd.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <dirent.h>
#include <sys/types.h>
@ -29,6 +31,10 @@ namespace fs
int
dirfd(DIR *dh_)
{
return ::dirfd(dh_);
int rv;
rv = ::dirfd(dh_);
return ::to_neg_errno(rv);
}
}

8
src/fs_dup.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <unistd.h>
@ -28,6 +30,10 @@ namespace fs
int
dup(const int fd_)
{
return ::dup(fd_);
int rv;
rv = ::dup(fd_);
return ::to_neg_errno(rv);
}
}

4
src/fs_dup2.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <unistd.h>
@ -33,6 +35,6 @@ namespace fs
rv = ::dup2(oldfd_,newfd_);
return ((rv == -1) ? -errno : rv);
return ::to_neg_errno(rv);
}
}

8
src/fs_faccessat.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <string>
#include <fcntl.h>
@ -34,7 +36,11 @@ namespace fs
const int mode_,
const int flags_)
{
return ::faccessat(dirfd_,path_,mode_,flags_);
int rv;
rv = ::faccessat(dirfd_,path_,mode_,flags_);
return ::to_neg_errno(rv);
}
static

9
src/fs_fadvise_posix.icpp

@ -26,6 +26,13 @@ namespace fs
const off_t len_,
const int advice_)
{
return ::posix_fadvise(fd_,offset_,len_,advice_);
int rv;
rv = ::posix_fadvise(fd_,offset_,len_,advice_);
// On success, zero is returned.
// On error, an error number is returned.
// Return negative error number like other calls.
return -rv;
}
}

4
src/fs_fadvise_unsupported.icpp

@ -14,7 +14,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include <cerrno>
namespace fs
@ -26,6 +26,6 @@ namespace fs
const off_t len_,
const int advice_)
{
return (errno=EOPNOTSUPP,-1);
return -EOPNOTSUPP;
}
}

10
src/fs_fallocate_linux.icpp

@ -14,7 +14,9 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <fcntl.h>
#include "to_neg_errno.hpp"
#include <sys/types.h>
namespace fs
@ -25,6 +27,10 @@ namespace fs
const off_t offset_,
const off_t len_)
{
return ::fallocate(fd_,mode_,offset_,len_);
int rv;
rv = ::fallocate(fd_,mode_,offset_,len_);
return ::to_neg_errno(rv);
}
}

68
src/fs_fallocate_osx.icpp

@ -14,48 +14,44 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "fs_fcntl.hpp"
#include "fs_ftruncate.hpp"
#include <fcntl.h>
#include <unistd.h>
namespace l
static
int
_fallocate_core(const int fd_,
const off_t offset_,
const off_t len_)
{
static
int
fallocate_core(const int fd_,
const off_t offset_,
const off_t len_)
{
int rv;
fstore_t store = {F_ALLOCATECONTIG,F_PEOFPOSMODE,offset,len,0};
rv = ::fcntl(fd_,F_PREALLOCATE,&store);
if(rv == -1)
{
store.fst_flags = F_ALLOCATEALL;
rv = ::fcntl(fd_,F_PREALLOCATE,&store);
}
if(rv == -1)
return rv;
return ::ftruncate(fd_,(offset_+len_));
}
int rv;
fstore_t store = {F_ALLOCATECONTIG,F_PEOFPOSMODE,offset,len,0};
rv = fs::fcntl(fd_,F_PREALLOCATE,&store);
if(rv < 0)
{
store.fst_flags = F_ALLOCATEALL;
rv = fs::fcntl(fd_,F_PREALLOCATE,&store);
}
if(rv < 0)
return rv;
rv = fs::ftruncate(fd_,(offset_+len_));
return rv;
}
namespace fs
int
fs::fallocate(const int fd_,
const int mode_,
const off_t offset_,
const off_t len_)
{
int
fallocate(const int fd_,
const int mode_,
const off_t offset_,
const off_t len_)
{
if(mode_)
return (errno=EOPNOTSUPP,-1);
return l::fallocate_core(fd_,offset_,len_);
}
if(mode_)
return -EOPNOTSUPP;
return ::_fallocate_core(fd_,offset_,len_);
}

11
src/fs_fallocate_posix.icpp

@ -27,9 +27,16 @@ namespace fs
const off_t offset_,
const off_t len_)
{
int rv;
if(mode_)
return (errno=EOPNOTSUPP,-1);
return -EOPNOTSUPP;
rv = ::posix_fallocate(fd_,offset_,len_);
return ::posix_fallocate(fd_,offset_,len_);
// Returns zero on success.
// Error number on failure.
// Return -errno.
return -rv;
}
}

4
src/fs_fallocate_unsupported.icpp

@ -16,6 +16,8 @@
#include "errno.hpp"
#include <sys/types.h>
namespace fs
{
@ -25,6 +27,6 @@ namespace fs
const off_t offset_,
const off_t len_)
{
return (errno=EOPNOTSUPP,-1);
return -EOPNOTSUPP;
}
}

21
src/fs_fchmod.hpp

@ -19,6 +19,7 @@
#pragma once
#include "fs_fstat.hpp"
#include "to_neg_errno.hpp"
#include <sys/stat.h>
@ -33,7 +34,11 @@ namespace fs
fchmod(const int fd_,
const mode_t mode_)
{
return ::fchmod(fd_,mode_);
int rv;
rv = ::fchmod(fd_,mode_);
return ::to_neg_errno(rv);
}
static
@ -42,7 +47,7 @@ namespace fs
fchmod(const int fd_,
const struct stat &st_)
{
return ::fchmod(fd_,st_.st_mode);
return fs::fchmod(fd_,st_.st_mode);
}
static
@ -54,20 +59,20 @@ namespace fs
int rv;
rv = fs::fchmod(fd_,st_);
if(rv == -1)
if(rv < 0)
{
int error;
int err;
struct stat tmpst;
error = errno;
err = rv;
rv = fs::fstat(fd_,&tmpst);
if(rv < 0)
return -1;
return rv;
if((st_.st_mode & MODE_BITS) != (tmpst.st_mode & MODE_BITS))
return (errno=error,-1);
return err;
}
return 0;
return rv;
}
}

10
src/fs_fchmodat.hpp

@ -18,7 +18,9 @@
#pragma once
#include <string>
#include "fs_fchmodat.hpp"
#include "to_neg_errno.hpp"
#include <fcntl.h>
#include <sys/stat.h>
@ -34,7 +36,11 @@ namespace fs
const mode_t mode_,
const int flags_)
{
return ::fchmodat(dirfd_,pathname_,mode_,flags_);
int rv;
rv = ::fchmodat(dirfd_,pathname_,mode_,flags_);
return ::to_neg_errno(rv);
}
static

18
src/fs_fchown.hpp

@ -18,7 +18,7 @@
#pragma once
#include "errno.hpp"
#include "to_neg_errno.hpp"
#include "fs_fstat.hpp"
#include <sys/stat.h>
@ -35,7 +35,11 @@ namespace fs
const uid_t uid_,
const gid_t gid_)
{
return ::fchown(fd_,uid_,gid_);
int rv;
rv = ::fchown(fd_,uid_,gid_);
return ::to_neg_errno(rv);
}
static
@ -56,19 +60,19 @@ namespace fs
int rv;
rv = fs::fchown(fd_,st_);
if(rv == -1)
if(rv < 0)
{
int error;
int err;
struct stat tmpst;
error = errno;
err = rv;
rv = fs::fstat(fd_,&tmpst);
if(rv < 0)
return -1;
return err;
if((st_.st_uid != tmpst.st_uid) ||
(st_.st_gid != tmpst.st_gid))
return (errno=error,-1);
return err;
}
return 0;

25
src/fs_fcntl.hpp

@ -1,5 +1,25 @@
/*
ISC License
Copyright (c) 2025, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "to_neg_errno.hpp"
#include <fcntl.h>
namespace fs
@ -14,7 +34,7 @@ namespace fs
rv = ::fcntl(fd_,op_);
return ((rv == -1) ? -errno : rv);
return ::to_neg_errno(rv);
}
static
@ -28,7 +48,7 @@ namespace fs
rv = ::fcntl(fd_,op_,arg_);
return ((rv == -1) ? -errno : rv);
return ::to_neg_errno(rv);
}
static
@ -53,6 +73,5 @@ namespace fs
#else
return -ENOTSUP;
#endif
}
}

10
src/fs_fdatasync.hpp

@ -22,7 +22,7 @@
#define _GNU_SOURCE
#endif
#include "errno.hpp"
#include "to_neg_errno.hpp"
#include <unistd.h>
@ -35,9 +35,13 @@ namespace fs
fdatasync(const int fd_)
{
#if _POSIX_SYNCHRONIZED_IO > 0
return ::fdatasync(fd_);
int rv;
rv = ::fdatasync(fd_);
return ::to_neg_errno(rv);
#else
return (errno=ENOSYS,-1);
return -ENOSYS;
#endif
}
}

16
src/fs_fgetxattr.hpp

@ -18,7 +18,7 @@
#pragma once
#include "errno.hpp"
#include "to_neg_errno.hpp"
#include "xattr.hpp"
#include <string>
@ -37,12 +37,16 @@ namespace fs
const size_t size_)
{
#ifdef USE_XATTR
return ::fgetxattr(fd_,
attrname_,
value_,
size_);
int rv;
rv = ::fgetxattr(fd_,
attrname_,
value_,
size_);
return ::to_neg_errno(rv);
#else
return (errno=ENOTSUP,-1);
return -ENOTSUP;
#endif
}

2
src/fs_ficlone_unsupported.icpp

@ -25,6 +25,6 @@ namespace fs
ficlone(const int src_fd_,
const int dst_fd_)
{
return (errno=EOPNOTSUPP,-1);
return -EOPNOTSUPP;
}
}

2
src/fs_file_size.cpp

@ -31,7 +31,7 @@ namespace fs
rv = fs::fstat(fd_,&st);
if(rv < 0)
return -1;
return rv;
return st.st_size;
}

18
src/fs_file_unchanged.hpp

@ -1,3 +1,21 @@
/*
ISC License
Copyright (c) 2025, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fs_fstat.hpp"

35
src/fs_findallfiles.cpp

@ -16,6 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_findallfiles.hpp"
#include "fs_exists.hpp"
#include "fs_path.hpp"
@ -23,23 +25,20 @@
#include <vector>
namespace fs
void
fs::findallfiles(const std::vector<std::string> &basepaths_,
const char *fusepath_,
std::vector<std::string> *paths_)
{
void
findallfiles(const std::vector<std::string> &basepaths_,
const char *fusepath_,
std::vector<std::string> *paths_)
{
std::string fullpath;
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{
fullpath = fs::path::make(basepaths_[i],fusepath_);
if(!fs::exists(fullpath))
continue;
paths_->push_back(fullpath);
}
}
std::string fullpath;
for(const auto &basepath : basepaths_)
{
fullpath = fs::path::make(basepath,fusepath_);
if(!fs::exists(fullpath))
continue;
paths_->push_back(fullpath);
}
}

87
src/fs_findonfs.cpp

@ -16,6 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_findonfs.hpp"
#include "branches.hpp"
#include "errno.hpp"
#include "fs_fstat.hpp"
@ -25,53 +27,48 @@
#include <string>
namespace l
static
int
_findonfs(const Branches::Ptr &branches_,
const std::string &fusepath_,
const int fd_,
std::string *basepath_)
{
static
int
findonfs(const Branches::Ptr &branches_,
const std::string &fusepath_,
const int fd_,
std::string *basepath_)
{
int rv;
dev_t dev;
struct stat st;
std::string fullpath;
rv = fs::fstat(fd_,&st);
if(rv < 0)
return -1;
dev = st.st_dev;
for(const auto &branch : *branches_)
{
fullpath = fs::path::make(branch.path,fusepath_);
rv = fs::lstat(fullpath,&st);
if(rv == -1)
continue;
if(st.st_dev != dev)
continue;
*basepath_ = branch.path;
return 0;
}
return (errno=ENOENT,-1);
}
int rv;
dev_t dev;
struct stat st;
std::string fullpath;
rv = fs::fstat(fd_,&st);
if(rv < 0)
return rv;
dev = st.st_dev;
for(const auto &branch : *branches_)
{
fullpath = fs::path::make(branch.path,fusepath_);
rv = fs::lstat(fullpath,&st);
if(rv < 0)
continue;
if(st.st_dev != dev)
continue;
*basepath_ = branch.path;
return 0;
}
return -ENOENT;
}
namespace fs
int
fs::findonfs(const Branches::Ptr &branches_,
const std::string &fusepath_,
const int fd_,
std::string *basepath_)
{
int
findonfs(const Branches::Ptr &branches_,
const std::string &fusepath_,
const int fd_,
std::string *basepath_)
{
return l::findonfs(branches_,fusepath_,fd_,basepath_);
}
return ::_findonfs(branches_,fusepath_,fd_,basepath_);
}

10
src/fs_flistxattr.hpp

@ -18,7 +18,7 @@
#pragma once
#include "errno.hpp"
#include "to_neg_errno.hpp"
#include "xattr.hpp"
#include <sys/types.h>
@ -34,9 +34,13 @@ namespace fs
const size_t size_)
{
#ifdef USE_XATTR
return ::flistxattr(fd_,list_,size_);
int rv;
rv = ::flistxattr(fd_,list_,size_);
return ::to_neg_errno(rv);
#else
return (errno=ENOTSUP,-1);
return -ENOTSUP;
#endif
}
}

8
src/fs_flock.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <sys/file.h>
@ -29,6 +31,10 @@ namespace fs
flock(const int fd_,
const int operation_)
{
return ::flock(fd_,operation_);
int rv;
rv = ::flock(fd_,operation_);
return ::to_neg_errno(rv);
}
}

10
src/fs_fsetxattr.hpp

@ -18,7 +18,7 @@
#pragma once
#include "errno.hpp"
#include "to_neg_errno.hpp"
#include "xattr.hpp"
#include <string>
@ -38,9 +38,13 @@ namespace fs
const int flags_)
{
#ifdef USE_XATTR
return ::fsetxattr(fd_,name_,value_,size_,flags_);
int rv;
rv = ::fsetxattr(fd_,name_,value_,size_,flags_);
return ::to_neg_errno(rv);
#else
return (errno=ENOTSUP,-1);
return -ENOTSUP;
#endif
}

5
src/fs_fstat.hpp

@ -19,7 +19,8 @@
#pragma once
#include <errno.h>
#include "to_neg_errno.hpp"
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@ -37,6 +38,6 @@ namespace fs
rv = ::fstat(fd_,st_);
return ((rv == -1) ? -errno : rv);
return ::to_neg_errno(rv);
}
}

7
src/fs_fstatat.hpp

@ -18,10 +18,9 @@
#pragma once
#include <sys/types.h>
#include "to_neg_errno.hpp"
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
namespace fs
@ -41,7 +40,7 @@ namespace fs
statbuf_,
flags_);
return ((rv == -1) ? -errno : rv);
return ::to_neg_errno(rv);
}
static

40
src/fs_fstatvfs.hpp

@ -0,0 +1,40 @@
/*
ISC License
Copyright (c) 2019, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "to_neg_errno.hpp"
#include <sys/statvfs.h>
namespace fs
{
static
inline
int
fstatvfs(const int fd_,
struct statvfs *st_)
{
int rv;
rv = ::fstatvfs(fd_,st_);
return ::to_neg_errno(rv);
}
}

8
src/fs_fsync.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <unistd.h>
@ -28,6 +30,10 @@ namespace fs
int
fsync(const int fd_)
{
return ::fsync(fd_);
int rv;
rv = ::fsync(fd_);
return ::to_neg_errno(rv);
}
}

9
src/fs_ftruncate.hpp

@ -18,7 +18,8 @@
#pragma once
#include <sys/types.h>
#include "to_neg_errno.hpp"
#include <unistd.h>
@ -30,6 +31,10 @@ namespace fs
ftruncate(const int fd_,
const off_t size_)
{
return ::ftruncate(fd_,size_);
int rv;
rv = ::ftruncate(fd_,size_);
return ::to_neg_errno(rv);
}
}

8
src/fs_futimens_freebsd_11.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <sys/stat.h>
@ -29,6 +31,10 @@ namespace fs
futimens(const int fd_,
const struct timespec ts_[2])
{
return ::futimens(fd_,ts_);
int rv;
rv = ::futimens(fd_,ts_);
return ::to_neg_errno(rv);
}
}

381
src/fs_futimens_generic.hpp

@ -34,228 +34,225 @@
#endif
namespace l
static
inline
bool
_can_call_lutimes(const int dirfd_,
const std::string &path_,
const int flags_)
{
static
inline
bool
can_call_lutimes(const int dirfd_,
const std::string &path_,
const int flags_)
{
return ((flags_ == AT_SYMLINK_NOFOLLOW) &&
((dirfd_ == AT_FDCWD) ||
(path_[0] == '/')));
}
return ((flags_ == AT_SYMLINK_NOFOLLOW) &&
((dirfd_ == AT_FDCWD) ||
(path_[0] == '/')));
}
static
inline
bool
should_ignore(const struct timespec ts_[2])
{
return ((ts_ != NULL) &&
(ts_[0].tv_nsec == UTIME_OMIT) &&
(ts_[1].tv_nsec == UTIME_OMIT));
}
static
inline
bool
_should_ignore(const struct timespec ts_[2])
{
return ((ts_ != NULL) &&
(ts_[0].tv_nsec == UTIME_OMIT) &&
(ts_[1].tv_nsec == UTIME_OMIT));
}
static
inline
bool
should_be_set_to_now(const struct timespec ts_[2])
{
return ((ts_ == NULL) ||
((ts_[0].tv_nsec == UTIME_NOW) &&
(ts_[1].tv_nsec == UTIME_NOW)));
}
static
inline
bool
_should_be_set_to_now(const struct timespec ts_[2])
{
return ((ts_ == NULL) ||
((ts_[0].tv_nsec == UTIME_NOW) &&
(ts_[1].tv_nsec == UTIME_NOW)));
}
static
inline
bool
timespec_invalid(const struct timespec &ts_)
{
return (((ts_.tv_nsec < 0) ||
(ts_.tv_nsec > 999999999)) &&
((ts_.tv_nsec != UTIME_NOW) &&
(ts_.tv_nsec != UTIME_OMIT)));
}
static
inline
bool
_timespec_invalid(const struct timespec &ts_)
{
return (((ts_.tv_nsec < 0) ||
(ts_.tv_nsec > 999999999)) &&
((ts_.tv_nsec != UTIME_NOW) &&
(ts_.tv_nsec != UTIME_OMIT)));
}
static
inline
bool
timespec_invalid(const struct timespec ts_[2])
{
return ((ts_ != NULL) &&
(l::timespec_invalid(ts_[0]) ||
l::timespec_invalid(ts_[1])));
}
static
inline
bool
_timespec_invalid(const struct timespec ts_[2])
{
return ((ts_ != NULL) &&
(::_timespec_invalid(ts_[0]) ||
::_timespec_invalid(ts_[1])));
}
static
inline
bool
flags_invalid(const int flags_)
{
return ((flags_ & ~AT_SYMLINK_NOFOLLOW) != 0);
}
static
inline
bool
_flags_invalid(const int flags_)
{
return ((flags_ & ~AT_SYMLINK_NOFOLLOW) != 0);
}
static
inline
bool
any_timespec_is_utime_omit(const struct timespec ts_[2])
{
return ((ts_[0].tv_nsec == UTIME_OMIT) ||
(ts_[1].tv_nsec == UTIME_OMIT));
}
static
inline
bool
_any_timespec_is_utime_omit(const struct timespec ts_[2])
{
return ((ts_[0].tv_nsec == UTIME_OMIT) ||
(ts_[1].tv_nsec == UTIME_OMIT));
}
static
inline
bool
any_timespec_is_utime_now(const struct timespec ts_[2])
{
return ((ts_[0].tv_nsec == UTIME_NOW) ||
(ts_[1].tv_nsec == UTIME_NOW));
}
static
inline
bool
_any_timespec_is_utime_now(const struct timespec ts_[2])
{
return ((ts_[0].tv_nsec == UTIME_NOW) ||
(ts_[1].tv_nsec == UTIME_NOW));
}
static
inline
int
set_utime_omit_to_current_value(const int dirfd_,
const std::string &path_,
const struct timespec ts_[2],
struct timeval tv_[2],
const int flags_)
{
int rv;
struct stat st;
timespec *atime;
timespec *mtime;
static
inline
int
_set_utime_omit_to_current_value(const int dirfd_,
const std::string &path_,
const struct timespec ts_[2],
struct timeval tv_[2],
const int flags_)
{
int rv;
struct stat st;
timespec *atime;
timespec *mtime;
if(!l::any_timespec_is_utime_omit(ts_))
return 0;
if(!::_any_timespec_is_utime_omit(ts_))
return 0;
rv = fs::fstatat(dirfd_,path_,&st,flags_);
if(rv < 0)
return rv;
rv = fs::fstatat(dirfd_,path_,&st,flags_);
if(rv < 0)
return rv;
atime = fs::stat_atime(st);
mtime = fs::stat_mtime(st);
atime = fs::stat_atime(st);
mtime = fs::stat_mtime(st);
if(ts_[0].tv_nsec == UTIME_OMIT)
TIMESPEC_TO_TIMEVAL(&tv[0],atime);
if(ts_[1].tv_nsec == UTIME_OMIT)
TIMESPEC_TO_TIMEVAL(&tv[1],mtime);
if(ts_[0].tv_nsec == UTIME_OMIT)
TIMESPEC_TO_TIMEVAL(&tv[0],atime);
if(ts_[1].tv_nsec == UTIME_OMIT)
TIMESPEC_TO_TIMEVAL(&tv[1],mtime);
return 0;
}
return 0;
}
static
inline
int
set_utime_omit_to_current_value(const int fd_,
const struct timespec ts_[2],
struct timeval tv_[2])
{
int rv;
struct stat st;
timespec *atime;
timespec *mtime;
static
inline
int
_set_utime_omit_to_current_value(const int fd_,
const struct timespec ts_[2],
struct timeval tv_[2])
{
int rv;
struct stat st;
timespec *atime;
timespec *mtime;
if(!l::any_timespec_is_utime_omit(ts_))
return 0;
if(!::_any_timespec_is_utime_omit(ts_))
return 0;
rv = fs::fstat(fd_,&st);
if(rv == -1)
return -1;
rv = fs::fstat(fd_,&st);
if(rv < 0)
return rv;
atime = fs::stat_atime(st);
mtime = fs::stat_mtime(st);
atime = fs::stat_atime(st);
mtime = fs::stat_mtime(st);
if(ts_[0].tv_nsec == UTIME_OMIT)
TIMESPEC_TO_TIMEVAL(&tv_[0],atime);
if(ts_[1].tv_nsec == UTIME_OMIT)
TIMESPEC_TO_TIMEVAL(&tv_[1],mtime);
if(ts_[0].tv_nsec == UTIME_OMIT)
TIMESPEC_TO_TIMEVAL(&tv_[0],atime);
if(ts_[1].tv_nsec == UTIME_OMIT)
TIMESPEC_TO_TIMEVAL(&tv_[1],mtime);
return 0;
}
return 0;
}
static
inline
int
set_utime_now_to_now(const struct timespec ts_[2],
struct timeval tv_[2])
{
int rv;
struct timeval now;
static
inline
int
_set_utime_now_to_now(const struct timespec ts_[2],
struct timeval tv_[2])
{
int rv;
struct timeval now;
if(l::any_timespec_is_utime_now(ts_))
return 0;
if(::_any_timespec_is_utime_now(ts_))
return 0;
rv = time::gettimeofday(&now,NULL);
if(rv == -1)
return -1;
rv = time::gettimeofday(&now,NULL);
if(rv < 0)
return rv;
if(ts_[0].tv_nsec == UTIME_NOW)
tv_[0] = now;
if(ts_[1].tv_nsec == UTIME_NOW)
tv_[1] = now;
if(ts_[0].tv_nsec == UTIME_NOW)
tv_[0] = now;
if(ts_[1].tv_nsec == UTIME_NOW)
tv_[1] = now;
return 0;
}
return 0;
}
static
inline
int
convert_timespec_to_timeval(const int dirfd_,
const std::string &path_,
const struct timespec ts_[2],
struct timeval tv_[2],
struct timeval **tvp_,
const int flags_)
{
int rv;
static
inline
int
_convert_timespec_to_timeval(const int dirfd_,
const std::string &path_,
const struct timespec ts_[2],
struct timeval tv_[2],
struct timeval **tvp_,
const int flags_)
{
int rv;
if(l::should_be_set_to_now(ts_))
return (tvp=NULL,0);
if(::_should_be_set_to_now(ts_))
return (tvp=NULL,0);
TIMESPEC_TO_TIMEVAL(&tv_[0],&ts_[0]);
TIMESPEC_TO_TIMEVAL(&tv_[1],&ts_[1]);
TIMESPEC_TO_TIMEVAL(&tv_[0],&ts_[0]);
TIMESPEC_TO_TIMEVAL(&tv_[1],&ts_[1]);
rv = l::set_utime_omit_to_current_value(dirfd_,path_,ts_,tv_,flags_);
if(rv == -1)
return -1;
rv = ::_set_utime_omit_to_current_value(dirfd_,path_,ts_,tv_,flags_);
if(rv < 0)
return rv;
rv = l::set_utime_now_to_now(ts_,tv_);
if(rv == -1)
return -1;
rv = ::_set_utime_now_to_now(ts_,tv_);
if(rv < 0)
return rv;
return (*tvp_=tv_,0);
}
return (*tvp_=tv_,0);
}
static
inline
int
convert_timespec_to_timeval(const int fd_,
const struct timespec ts_[2],
struct timeval tv_[2],
struct timeval **tvp_)
{
int rv;
static
inline
int
_convert_timespec_to_timeval(const int fd_,
const struct timespec ts_[2],
struct timeval tv_[2],
struct timeval **tvp_)
{
int rv;
if(l::should_be_set_to_now(ts_))
return (*tvp=NULL,0);
if(::_should_be_set_to_now(ts_))
return (*tvp=NULL,0);
TIMESPEC_TO_TIMEVAL(&tv_[0],&ts_[0]);
TIMESPEC_TO_TIMEVAL(&tv_[1],&ts_[1]);
TIMESPEC_TO_TIMEVAL(&tv_[0],&ts_[0]);
TIMESPEC_TO_TIMEVAL(&tv_[1],&ts_[1]);
rv = l::set_utime_omit_to_current_value(fd_,ts_,tv_);
if(rv == -1)
return -1;
rv = ::_set_utime_omit_to_current_value(fd_,ts_,tv_);
if(rv < 0)
return rv;
rv = l::set_utime_now_to_now(ts_,tv_);
if(rv == -1)
return -1;
rv = ::_set_utime_now_to_now(ts_,tv_);
if(rv < 0)
return rv;
return (*tvp=tv,0);
}
return (*tvp=tv,0);
}
namespace fs
@ -270,15 +267,15 @@ namespace fs
struct timeval tv[2];
struct timeval *tvp;
if(l::timespec_invalid(ts_))
return (errno=EINVAL,-1);
if(l::should_ignore(ts_))
if(::_timespec_invalid(ts_))
return -EINVAL;
if(::_should_ignore(ts_))
return 0;
rv = l::convert_timespec_to_timeval(fd_,ts_,tv,&tvp);
if(rv == -1)
return -1;
rv = ::_convert_timespec_to_timeval(fd_,ts_,tv,&tvp);
if(rv < 0)
return rv;
return ::futimes(fd_,tvp);
return fs::futimes(fd_,tvp);
}
}

8
src/fs_futimens_linux.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <sys/stat.h>
@ -29,6 +31,10 @@ namespace fs
futimens(const int fd_,
const struct timespec ts_[2])
{
return ::futimens(fd_,ts_);
int rv;
rv = ::futimens(fd_,ts_);
return ::to_neg_errno(rv);
}
}

8
src/fs_futimesat_generic.icpp

@ -16,6 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "to_neg_errno.hpp"
#include <fcntl.h>
#include <sys/time.h>
@ -27,6 +29,10 @@ namespace fs
const char *pathname_,
const struct timeval times_[2])
{
return ::futimesat(dirfd_,pathname_,times_);
int rv;
rv = ::futimesat(dirfd_,pathname_,times_);
return ::to_neg_errno(rv);
}
}

32
src/fs_futimesat_osx.icpp

@ -16,6 +16,10 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_fstat.hpp"
#include "fs_fcntl.hpp"
#include "fs_utimes.hpp"
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
@ -38,24 +42,24 @@ namespace l
int rv;
struct stat st;
rv = ::fstat(dirfd_,&st);
if(rv == -1)
return -1;
rv = fs::fstat(dirfd_,&st);
if(rv < 0)
return rv;
if(!S_ISDIR(st.st_mode))
return (errno=ENOTDIR,-1);
return -ENOTDIR;
rv = ::fcntl(dirfd_,F_GETPATH,fullpath);
if(rv == -1)
return -1;
rv = fs::fcntl(dirfd_,F_GETPATH,fullpath);
if(rv < 0)
return rv;
rv = ::strlcat(fullpath_,"/",MAXPATHLEN);
if(rv > MAXPATHLEN)
return (errno=ENAMETOOLONG,-1);
return -ENAMETOOLONG;
rv = ::strlcat(fullpath_,path_,MAXPATHLEN);
if(rv > MAXPATHLEN)
return (errno=ENAMETOOLONG,-1);
return -ENAMETOOLONG;
return 0;
}
@ -74,15 +78,15 @@ namespace fs
if((dirfd_ == AT_FDCWD) ||
((pathname_ != NULL) &&
(pathname_[0] == '/')))
return ::utimes(pathname_,times_);
return fs::utimes(pathname_,times_);
if(dirfd_ < 0)
return (errno=EBADF,-1);
return -EBADF;
rv = l::getpath(dirfd_,pathname_,fullpath);
if(rv == -1)
return -1;
if(rv < 0)
return rv;
return ::utimes(fullpath,times_);
return fs::utimes(fullpath,times_);
}
}

16
src/fs_getdents64.cpp

@ -16,7 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "to_neg_errno.hpp"
#if defined __linux__
#include <unistd.h>
@ -27,14 +27,18 @@
namespace fs
{
int
getdents_64(unsigned int fd_,
void *dirp_,
unsigned int count_)
getdents64(unsigned int fd_,
void *dirp_,
unsigned int count_)
{
#if defined SYS_getdents64
return ::syscall(SYS_getdents64,fd_,dirp_,count_);
int rv;
rv = ::syscall(SYS_getdents64,fd_,dirp_,count_);
return ::to_neg_errno(rv);
#else
return (errno=ENOTSUP,-1);
return -ENOTSUP;
#endif
}
}

6
src/fs_getdents64.hpp

@ -22,7 +22,7 @@
namespace fs
{
int
getdents_64(unsigned int fd,
void *dirp,
unsigned int count);
getdents64(unsigned int fd,
void *dirp,
unsigned int count);
}

4
src/fs_getfl.cpp

@ -16,7 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <fcntl.h>
#include "fs_fcntl.hpp"
namespace fs
@ -24,6 +24,6 @@ namespace fs
int
getfl(const int fd_)
{
return ::fcntl(fd_,F_GETFL,0);
return fs::fcntl(fd_,F_GETFL,0);
}
}

25
src/fs_glob.cpp

@ -14,6 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_glob.hpp"
#include <glob.h>
#include <cstdint>
@ -31,21 +33,18 @@ using std::vector;
#define GLOB_ONLYDIR 0
#endif
namespace fs
void
fs::glob(const string &pattern_,
vector<string> *strs_)
{
void
glob(const string &pattern_,
vector<string> *strs_)
{
int flags;
glob_t gbuf = {0};
int flags;
glob_t gbuf = {0};
flags = (GLOB_BRACE|GLOB_ONLYDIR);
::glob(pattern_.c_str(),flags,NULL,&gbuf);
flags = (GLOB_BRACE|GLOB_ONLYDIR);
::glob(pattern_.c_str(),flags,NULL,&gbuf);
for(size_t i = 0; i < gbuf.gl_pathc; i++)
strs_->push_back(gbuf.gl_pathv[i]);
for(size_t i = 0; i < gbuf.gl_pathc; i++)
strs_->push_back(gbuf.gl_pathv[i]);
::globfree(&gbuf);
}
::globfree(&gbuf);
}

27
src/fs_has_space.cpp

@ -16,6 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_has_space.hpp"
#include "fs_statvfs.hpp"
#include "statvfs_util.hpp"
@ -23,19 +25,16 @@
#include <string>
namespace fs
bool
fs::has_space(const std::string &str_,
const int64_t size_)
{
bool
has_space(const std::string &str_,
const int64_t size_)
{
int rv;
struct statvfs st;
rv = fs::statvfs(str_,&st);
if(rv == -1)
return false;
return (StatVFS::spaceavail(st) > size_);
}
int rv;
struct statvfs st;
rv = fs::statvfs(str_,&st);
if(rv < 0)
return false;
return (StatVFS::spaceavail(st) > size_);
}

35
src/fs_info.cpp

@ -16,6 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_info.hpp"
#include "fs_info_t.hpp"
#include "fs_path.hpp"
#include "fs_stat.hpp"
@ -29,23 +31,20 @@
using std::string;
namespace fs
int
fs::info(const string &path_,
fs::info_t *info_)
{
int
info(const string &path_,
fs::info_t *info_)
{
int rv;
struct statvfs st;
rv = fs::statvfs_cache(path_.c_str(),&st);
if(rv == 0)
{
info_->readonly = StatVFS::readonly(st);
info_->spaceavail = StatVFS::spaceavail(st);
info_->spaceused = StatVFS::spaceused(st);
}
return rv;
}
int rv;
struct statvfs st;
rv = fs::statvfs_cache(path_.c_str(),&st);
if(rv == 0)
{
info_->readonly = StatVFS::readonly(st);
info_->spaceavail = StatVFS::spaceavail(st);
info_->spaceused = StatVFS::spaceused(st);
}
return rv;
}

246
src/fs_inode.cpp

@ -31,18 +31,18 @@ typedef uint64_t (*inodefunc_t)(const std::string_view,
const mode_t,
const ino_t);
static uint64_t hybrid_hash(const std::string_view,
const std::string_view,
const mode_t,
const ino_t);
static uint64_t _hybrid_hash(const std::string_view,
const std::string_view,
const mode_t,
const ino_t);
static inodefunc_t g_func = hybrid_hash;
static inodefunc_t g_func = ::_hybrid_hash;
static
uint32_t
h64_to_h32(uint64_t h_)
_h64_to_h32(uint64_t h_)
{
h_ ^= (h_ >> 32);
h_ *= 0x9E3779B9;
@ -51,20 +51,20 @@ h64_to_h32(uint64_t h_)
static
uint64_t
passthrough(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
_passthrough(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
{
return ino_;
}
static
uint64_t
path_hash(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
_path_hash(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
{
uint64_t seed;
@ -75,27 +75,27 @@ path_hash(const std::string_view branch_path_,
static
uint64_t
path_hash32(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
_path_hash32(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
{
uint64_t h;
h = path_hash(branch_path_,
fusepath_,
mode_,
ino_);
h = ::_path_hash(branch_path_,
fusepath_,
mode_,
ino_);
return h64_to_h32(h);
return ::_h64_to_h32(h);
}
static
uint64_t
devino_hash(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
_devino_hash(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
{
uint64_t seed;
@ -107,122 +107,116 @@ devino_hash(const std::string_view branch_path_,
static
uint64_t
devino_hash32(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
_devino_hash32(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
{
uint64_t h;
h = devino_hash(branch_path_,
fusepath_,
mode_,
ino_);
h = ::_devino_hash(branch_path_,
fusepath_,
mode_,
ino_);
return h64_to_h32(h);
return ::_h64_to_h32(h);
}
static
uint64_t
hybrid_hash(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
_hybrid_hash(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
{
return (S_ISDIR(mode_) ?
path_hash(branch_path_,fusepath_,mode_,ino_) :
devino_hash(branch_path_,fusepath_,mode_,ino_));
::_path_hash(branch_path_,fusepath_,mode_,ino_) :
::_devino_hash(branch_path_,fusepath_,mode_,ino_));
}
static
uint64_t
hybrid_hash32(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
_hybrid_hash32(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
{
return (S_ISDIR(mode_) ?
path_hash32(branch_path_,fusepath_,mode_,ino_) :
devino_hash32(branch_path_,fusepath_,mode_,ino_));
::_path_hash32(branch_path_,fusepath_,mode_,ino_) :
::_devino_hash32(branch_path_,fusepath_,mode_,ino_));
}
int
fs::inode::set_algo(const std::string &algo_)
{
if(algo_ == "passthrough")
g_func = ::_passthrough;
ef(algo_ == "path-hash")
g_func = ::_path_hash;
ef(algo_ == "path-hash32")
g_func = ::_path_hash32;
ef(algo_ == "devino-hash")
g_func = ::_devino_hash;
ef(algo_ == "devino-hash32")
g_func = ::_devino_hash32;
ef(algo_ == "hybrid-hash")
g_func = ::_hybrid_hash;
ef(algo_ == "hybrid-hash32")
g_func = ::_hybrid_hash32;
else
return -EINVAL;
return 0;
}
namespace fs
std::string
fs::inode::get_algo(void)
{
if(g_func == ::_passthrough)
return "passthrough";
if(g_func == ::_path_hash)
return "path-hash";
if(g_func == ::_path_hash32)
return "path-hash32";
if(g_func == ::_devino_hash)
return "devino-hash";
if(g_func == ::_devino_hash32)
return "devino-hash32";
if(g_func == ::_hybrid_hash)
return "hybrid-hash";
if(g_func == ::_hybrid_hash32)
return "hybrid-hash32";
return {};
}
uint64_t
fs::inode::calc(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
{
namespace inode
{
int
set_algo(const std::string &algo_)
{
if(algo_ == "passthrough")
g_func = passthrough;
ef(algo_ == "path-hash")
g_func = path_hash;
ef(algo_ == "path-hash32")
g_func = path_hash32;
ef(algo_ == "devino-hash")
g_func = devino_hash;
ef(algo_ == "devino-hash32")
g_func = devino_hash32;
ef(algo_ == "hybrid-hash")
g_func = hybrid_hash;
ef(algo_ == "hybrid-hash32")
g_func = hybrid_hash32;
else
return -EINVAL;
return 0;
}
std::string
get_algo(void)
{
if(g_func == passthrough)
return "passthrough";
if(g_func == path_hash)
return "path-hash";
if(g_func == path_hash32)
return "path-hash32";
if(g_func == devino_hash)
return "devino-hash";
if(g_func == devino_hash32)
return "devino-hash32";
if(g_func == hybrid_hash)
return "hybrid-hash";
if(g_func == hybrid_hash32)
return "hybrid-hash32";
return std::string();
}
uint64_t
calc(const std::string_view branch_path_,
const std::string_view fusepath_,
const mode_t mode_,
const ino_t ino_)
{
return g_func(branch_path_,fusepath_,mode_,ino_);
}
void
calc(const std::string_view branch_path_,
const std::string_view fusepath_,
struct stat *st_)
{
st_->st_ino = calc(branch_path_,
fusepath_,
st_->st_mode,
st_->st_ino);
}
void
calc(const std::string_view branch_path_,
const std::string_view fusepath_,
struct fuse_statx *st_)
{
st_->ino = calc(branch_path_,
fusepath_,
st_->mode,
st_->ino);
}
}
return g_func(branch_path_,fusepath_,mode_,ino_);
}
void
fs::inode::calc(const std::string_view branch_path_,
const std::string_view fusepath_,
struct stat *st_)
{
st_->st_ino = calc(branch_path_,
fusepath_,
st_->st_mode,
st_->st_ino);
}
void
fs::inode::calc(const std::string_view branch_path_,
const std::string_view fusepath_,
struct fuse_statx *st_)
{
st_->ino = calc(branch_path_,
fusepath_,
st_->mode,
st_->ino);
}

8
src/fs_ioctl.hpp

@ -18,7 +18,7 @@
#pragma once
#include "errno.hpp"
#include "to_neg_errno.hpp"
#include <sys/ioctl.h>
@ -35,7 +35,7 @@ namespace fs
rv = ::ioctl(fd_,request_);
return ((rv == -1) ? -errno : rv);
return ::to_neg_errno(rv);
}
static
@ -49,7 +49,7 @@ namespace fs
rv = ::ioctl(fd_,request_,data_);
return ((rv == -1) ? -errno : rv);
return ::to_neg_errno(rv);
}
static
@ -63,6 +63,6 @@ namespace fs
rv = ::ioctl(fd_,request_,int_);
return ((rv == -1) ? -errno : rv);
return ::to_neg_errno(rv);
}
}

3
src/fs_is_rofs.hpp

@ -18,6 +18,7 @@
#pragma once
#include "fs_close.hpp"
#include "fs_mktemp.hpp"
#include "fs_statvfs.hpp"
#include "fs_unlink.hpp"
@ -26,6 +27,8 @@
#include <string>
#include <fcntl.h>
namespace fs
{

31
src/fs_lchmod.hpp

@ -19,11 +19,17 @@
#pragma once
#include "fs_lstat.hpp"
#include "to_neg_errno.hpp"
#include <string>
#include <sys/stat.h>
#if defined __linux__
#include <fcntl.h>
#include <sys/stat.h>
#endif
#define MODE_BITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
@ -36,9 +42,18 @@ namespace fs
const mode_t mode_)
{
#if defined __linux__
return ::chmod(pathname_,mode_);
int rv;
const int flags = AT_SYMLINK_NOFOLLOW;
rv = ::fchmodat(AT_FDCWD,pathname_,mode_,flags);
return ::to_neg_errno(rv);
#else
return ::lchmod(pathname_,mode_);
int rv;
rv = ::lchmod(pathname_,mode_);
return ::to_neg_errno(rv);
#endif
}
@ -60,18 +75,18 @@ namespace fs
int rv;
rv = fs::lchmod(path_,mode_);
if(rv == -1)
if(rv < 0)
{
int error;
int err;
struct stat st;
error = errno;
err = rv;
rv = fs::lstat(path_,&st);
if(rv == -1)
return -1;
if(rv < 0)
return rv;
if((st.st_mode & MODE_BITS) != (mode_ & MODE_BITS))
return (errno=error,-1);
return err;
}
return 0;

19
src/fs_lchown.hpp

@ -19,6 +19,7 @@
#pragma once
#include "fs_lstat.hpp"
#include "to_neg_errno.hpp"
#include <unistd.h>
@ -32,7 +33,11 @@ namespace fs
const uid_t uid_,
const gid_t gid_)
{
return ::lchown(pathname_,uid_,gid_);
int rv;
rv = ::lchown(pathname_,uid_,gid_);
return ::to_neg_errno(rv);
}
static
@ -72,19 +77,19 @@ namespace fs
int rv;
rv = fs::lchown(path_,st_);
if(rv == -1)
if(rv < 0)
{
int error;
int err;
struct stat tmpst;
error = errno;
err = rv;
rv = fs::lstat(path_,&tmpst);
if(rv == -1)
return -1;
if(rv < 0)
return err;
if((st_.st_uid != tmpst.st_uid) ||
(st_.st_gid != tmpst.st_gid))
return (errno=error,-1);
return err;
}
return 0;

16
src/fs_lgetxattr.hpp

@ -18,7 +18,7 @@
#pragma once
#include "errno.hpp"
#include "to_neg_errno.hpp"
#include "xattr.hpp"
#include <string>
@ -37,12 +37,16 @@ namespace fs
const size_t size_)
{
#ifdef USE_XATTR
return ::lgetxattr(path_,
attrname_,
value_,
size_);
int rv;
rv = ::lgetxattr(path_,
attrname_,
value_,
size_);
return ::to_neg_errno(rv);
#else
return (errno=ENOTSUP,-1);
return -ENOTSUP;
#endif
}

10
src/fs_link.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <string>
#include <unistd.h>
@ -31,7 +33,11 @@ namespace fs
link(const std::string &oldpath_,
const std::string &newpath_)
{
return ::link(oldpath_.c_str(),
newpath_.c_str());
int rv;
rv = ::link(oldpath_.c_str(),
newpath_.c_str());
return ::to_neg_errno(rv);
}
}

4
src/fs_llistxattr.hpp

@ -18,7 +18,7 @@
#pragma once
#include "errno.hpp"
#include "to_neg_errno.hpp"
#include "xattr.hpp"
#include <string>
@ -40,7 +40,7 @@ namespace fs
rv = ::llistxattr(path_,list_,size_);
return ((rv == -1) ? -errno : rv);
return ::to_neg_errno(rv);
#else
return -ENOTSUP;
#endif

10
src/fs_lremovexattr.hpp

@ -18,7 +18,7 @@
#pragma once
#include "errno.hpp"
#include "to_neg_errno.hpp"
#include "xattr.hpp"
#include <sys/types.h>
@ -33,9 +33,13 @@ namespace fs
const char *attrname_)
{
#ifdef USE_XATTR
return ::lremovexattr(path_.c_str(),attrname_);
int rv;
rv = ::lremovexattr(path_.c_str(),attrname_);
return ::to_neg_errno(rv);
#else
return (errno=ENOTSUP,-1);
return -ENOTSUP;
#endif
}
}

8
src/fs_lseek.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <sys/types.h>
#include <unistd.h>
@ -31,6 +33,10 @@ namespace fs
const off_t offset_,
const int whence_)
{
return ::lseek(fd_,offset_,whence_);
off_t rv;
rv = ::lseek(fd_,offset_,whence_);
return ::to_neg_errno(rv);
}
}

18
src/fs_lsetxattr.hpp

@ -18,7 +18,7 @@
#pragma once
#include "errno.hpp"
#include "to_neg_errno.hpp"
#include "xattr.hpp"
#include <string>
@ -38,13 +38,17 @@ namespace fs
const int flags_)
{
#ifdef USE_XATTR
return ::lsetxattr(path_,
name_,
value_,
size_,
flags_);
int rv;
rv = ::lsetxattr(path_,
name_,
value_,
size_,
flags_);
return ::to_neg_errno(rv);
#else
return (errno=ENOTSUP,-1);
return -ENOTSUP;
#endif
}

8
src/fs_lstat.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <string>
#include <sys/stat.h>
@ -33,7 +35,11 @@ namespace fs
lstat(const char *path_,
struct stat *st_)
{
return ::lstat(path_,st_);
int rv;
rv = ::lstat(path_,st_);
return ::to_neg_errno(rv);
}
static

55
src/fs_lstatvfs.hpp

@ -0,0 +1,55 @@
/*
ISC License
Copyright (c) 2019, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "errno.hpp"
#include "fs_close.hpp"
#include "fs_open.hpp"
#include "fs_fstatvfs.hpp"
#include <cstdint>
#include <string>
#ifndef O_PATH
# define O_PATH 0
#endif
namespace fs
{
static
inline
int
lstatvfs(const std::string &path_,
struct statvfs *st_)
{
int fd;
int rv;
fd = fs::open(path_,O_RDONLY|O_NOFOLLOW|O_PATH);
if(fd < 0)
return fd;
rv = fs::fstatvfs(fd,st_);
fs::close(fd);
return rv;
}
}

8
src/fs_mkdir.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include "fs_path.hpp"
#include <string>
@ -34,7 +36,11 @@ namespace fs
mkdir(const char *path_,
const mode_t mode_)
{
return ::mkdir(path_,mode_);
int rv;
rv = ::mkdir(path_,mode_);
return ::to_neg_errno(rv);
}
static

19
src/fs_mknod.hpp

@ -18,14 +18,29 @@
#pragma once
#include "to_neg_errno.hpp"
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
namespace fs
{
static
inline
int
mknod(const char *path_,
const mode_t mode_,
const dev_t dev_)
{
int rv;
rv = ::mknod(path_,mode_,dev_);
return ::to_neg_errno(rv);
}
static
inline
int
@ -33,6 +48,6 @@ namespace fs
const mode_t mode_,
const dev_t dev_)
{
return ::mknod(path_.c_str(),mode_,dev_);
return fs::mknod(path_.c_str(),mode_,dev_);
}
}

133
src/fs_mktemp.cpp

@ -16,6 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_mktemp.hpp"
#include "errno.hpp"
#include "fs_open.hpp"
#include "fs_path.hpp"
@ -36,77 +38,70 @@ static char const CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmno
static size_t const CHARS_SIZE = (sizeof(CHARS) - 1);
namespace l
static
std::string
_generate_tmp_path(const std::string &dirpath_,
const std::string &filename_)
{
long name_max;
size_t substr_len;
fs::Path path;
std::string filename;
name_max = ::pathconf(dirpath_.c_str(),_PC_NAME_MAX);
if(name_max == -1)
name_max = NAME_MAX;
substr_len = std::min(filename_.size(),
(size_t)(name_max - PAD_LEN - 2ULL));
filename = '.';
filename += filename_.substr(0,substr_len);
filename += '_';
for(size_t i = 0; i < PAD_LEN; i++)
filename += CHARS[RND::rand64(CHARS_SIZE)];
path = dirpath_;
path /= filename;
return path.string();
}
std::tuple<int,std::string>
fs::mktemp_in_dir(const std::string &dirpath_,
const std::string &filename_,
const int flags_)
{
static
std::string
generate_tmp_path(const std::string &dirpath_,
const std::string &filename_)
{
long name_max;
size_t substr_len;
fs::Path path;
std::string filename;
name_max = pathconf(dirpath_.c_str(),_PC_NAME_MAX);
if(name_max == -1)
name_max = NAME_MAX;
substr_len = std::min(filename_.size(),
(size_t)(name_max - PAD_LEN - 2ULL));
filename = '.';
filename += filename_.substr(0,substr_len);
filename += '_';
for(size_t i = 0; i < PAD_LEN; i++)
filename += CHARS[RND::rand64(CHARS_SIZE)];
path = dirpath_;
path /= filename;
return path.string();
}
int fd;
int count;
int flags;
std::string tmp_filepath;
count = MAX_ATTEMPTS;
flags = (flags_ | O_EXCL | O_CREAT);
while(count-- > 0)
{
tmp_filepath = ::_generate_tmp_path(dirpath_,filename_);
fd = fs::open(tmp_filepath,flags,S_IRUSR|S_IWUSR);
if(fd == -EEXIST)
continue;
if(fd < 0)
return std::make_tuple(fd,std::string());
return std::make_tuple(fd,tmp_filepath);
}
return std::make_tuple(-EEXIST,std::string());
}
namespace fs
std::tuple<int,std::string>
fs::mktemp(const std::string &filepath_,
const int flags_)
{
std::tuple<int,std::string>
mktemp_in_dir(const std::string &dirpath_,
const std::string &filename_,
const int flags_)
{
int fd;
int count;
int flags;
std::string tmp_filepath;
fd = -1;
count = MAX_ATTEMPTS;
flags = (flags_ | O_EXCL | O_CREAT);
while(count-- > 0)
{
tmp_filepath = l::generate_tmp_path(dirpath_,filename_);
fd = fs::open(tmp_filepath,flags,S_IRUSR|S_IWUSR);
if((fd == -1) && (errno == EEXIST))
continue;
if(fd == -1)
return std::make_tuple(-errno,std::string());
return std::make_tuple(fd,tmp_filepath);
}
return std::make_tuple(-EEXIST,std::string());
}
std::tuple<int,std::string>
mktemp(const std::string &filepath_,
const int flags_)
{
fs::Path filepath{filepath_};
return fs::mktemp_in_dir(filepath.parent_path(),
filepath.filename(),
flags_);
}
fs::Path filepath{filepath_};
return fs::mktemp_in_dir(filepath.parent_path(),
filepath.filename(),
flags_);
}

6
src/fs_mounts.cpp

@ -10,12 +10,12 @@ fs::mounts(fs::MountVec &mounts_)
{
FILE *f;
f = setmntent("/proc/mounts","r");
f = ::setmntent("/proc/mounts","r");
if(f == NULL)
return;
struct mntent *entry;
while((entry = getmntent(f)) != NULL)
while((entry = ::getmntent(f)) != NULL)
{
fs::Mount m;
@ -27,7 +27,7 @@ fs::mounts(fs::MountVec &mounts_)
mounts_.emplace_back(std::move(m));
}
endmntent(f);
::endmntent(f);
}
#else
void

16
src/fs_movefile_and_open.cpp

@ -79,16 +79,16 @@ _movefile_and_open(const Policy::Create &createFunc_,
src_branch = branchpath_;
rv = createFunc_(branches_,fusepath_.c_str(),dst_branch);
if(rv == -1)
return -errno;
if(rv < 0)
return rv;
origfd_flags = fs::getfl(origfd_);
if(origfd_flags == -1)
return -errno;
if(origfd_flags < 0)
return origfd_flags;
src_size = fs::file_size(origfd_);
if(src_size == -1)
return -errno;
if(src_size < 0)
return src_size;
if(fs::has_space(dst_branch[0]->path,src_size) == false)
return -ENOSPC;
@ -96,7 +96,7 @@ _movefile_and_open(const Policy::Create &createFunc_,
fusedir = fs::path::dirname(fusepath_);
rv = fs::clonepath(src_branch,dst_branch[0]->path,fusedir);
if(rv == -1)
if(rv < 0)
return -ENOSPC;
src_filepath = fs::path::make(src_branch,fusepath_);
@ -108,7 +108,7 @@ _movefile_and_open(const Policy::Create &createFunc_,
dstfd_flags = ::_cleanup_flags(origfd_flags);
rv = fs::open(dst_filepath,dstfd_flags);
if(rv == -1)
if(rv < 0)
return -ENOSPC;
fs::unlink(src_filepath);

14
src/fs_open.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <string>
#include <fcntl.h>
@ -33,7 +35,11 @@ namespace fs
open(const char *path_,
const int flags_)
{
return ::open(path_,flags_);
int rv;
rv = ::open(path_,flags_);
return ::to_neg_errno(rv);
}
static
@ -43,7 +49,11 @@ namespace fs
const int flags_,
const mode_t mode_)
{
return ::open(path_,flags_,mode_);
int rv;
rv = ::open(path_,flags_,mode_);
return ::to_neg_errno(rv);
}
static

5
src/fs_openat.hpp

@ -18,10 +18,11 @@
#pragma once
#include "to_neg_errno.hpp"
#include <filesystem>
#include <string>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
@ -40,7 +41,7 @@ namespace fs
rv = ::openat(dirfd_,pathname_,flags_,mode_);
return ((rv == -1) ? -errno : rv);
return ::to_neg_errno(rv);
}
static

10
src/fs_opendir.hpp

@ -26,11 +26,19 @@
namespace fs
{
static
inline
DIR *
opendir(const char *name_)
{
return ::opendir(name_);
}
static
inline
DIR *
opendir(const std::string &name_)
{
return ::opendir(name_.c_str());
return fs::opendir(name_.c_str());
}
}

50
src/fs_path.cpp

@ -26,40 +26,34 @@
using std::string;
namespace fs
string
fs::path::dirname(const char *path_)
{
namespace path
{
string
dirname(const char *path_)
{
string path(path_);
string path(path_);
return fs::path::dirname(path);
}
return fs::path::dirname(path);
}
string
dirname(const string &path_)
{
std::size_t i;
string
fs::path::dirname(const string &path_)
{
std::size_t i;
i = path_.size() - 1;
while((i > 0) && (path_[i] == '/'))
i--;
i = path_.size() - 1;
while((i > 0) && (path_[i] == '/'))
i--;
while((i > 0) && (path_[i] != '/'))
i--;
while((i > 0) && (path_[i] != '/'))
i--;
while((i > 0) && (path_[i] == '/'))
i--;
while((i > 0) && (path_[i] == '/'))
i--;
return path_.substr(0,i+1);
}
return path_.substr(0,i+1);
}
string
basename(const string &path_)
{
return path_.substr(path_.find_last_of('/')+1);
}
}
string
fs::path::basename(const string &path_)
{
return path_.substr(path_.find_last_of('/')+1);
}

2
src/fs_path.hpp

@ -86,4 +86,4 @@ namespace fs
return (base_ + suffix_);
}
}
};
}

4
src/fs_pread.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <unistd.h>
namespace fs
@ -33,6 +35,6 @@ namespace fs
rv = ::pread(fd_,buf_,count_,offset_);
return ((rv == -1) ? -errno : rv);
return ::to_neg_errno(rv);
}
}

6
src/fs_pwrite.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <unistd.h>
@ -34,9 +36,7 @@ namespace fs
ssize_t rv;
rv = ::pwrite(fd_,buf_,count_,offset_);
if(rv == -1)
return -errno;
return rv;
return ::to_neg_errno(rv);
}
}

17
src/fs_read.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <unistd.h>
@ -30,17 +32,10 @@ namespace fs
void *buf_,
const size_t count_)
{
return ::read(fd_,buf_,count_);
}
int rv;
static
inline
ssize_t
pread(const int fd_,
void *buf_,
const size_t count_,
const off_t offset_)
{
return ::pread(fd_,buf_,count_,offset_);
rv = ::read(fd_,buf_,count_);
return ::to_neg_errno(rv);
}
}

20
src/fs_readahead.cpp

@ -31,15 +31,13 @@
# include <sys/sysmacros.h>
#endif
namespace l
static
std::string
_generate_readahead_sys_path(const std::uint64_t major_,
const std::uint64_t minor_)
{
static
std::string
generate_readahead_sys_path(const std::uint64_t major_,
const std::uint64_t minor_)
{
return fmt::format("/sys/class/bdi/{}:{}/read_ahead_kb",major_,minor_);
}
return fmt::format("/sys/class/bdi/{}:{}/read_ahead_kb",major_,minor_);
}
int
@ -50,7 +48,7 @@ fs::readahead(const std::uint64_t major_dev_,
std::string syspath;
std::ofstream ofs;
syspath = l::generate_readahead_sys_path(major_dev_,minor_dev_);
syspath = ::_generate_readahead_sys_path(major_dev_,minor_dev_);
ofs.open(syspath);
if(ofs)
@ -83,8 +81,8 @@ fs::readahead(const std::string path_,
struct stat st;
rv = fs::lstat(path_,&st);
if(rv == -1)
return -errno;
if(rv < 0)
return rv;
return fs::readahead(st.st_dev,size_in_kb_);
}

10
src/fs_readlink.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <string>
#include <unistd.h>
@ -27,11 +29,15 @@ namespace fs
{
static
inline
int
ssize_t
readlink(const std::string &path_,
char *buf_,
const size_t bufsiz_)
{
return ::readlink(path_.c_str(),buf_,bufsiz_);
ssize_t rv;
rv = ::readlink(path_.c_str(),buf_,bufsiz_);
return ::to_neg_errno(rv);
}
}

32
src/fs_realpathize.cpp

@ -16,28 +16,26 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_realpathize.hpp"
#include "fs_realpath.hpp"
#include <string>
#include <vector>
namespace fs
void
fs::realpathize(std::vector<std::string> *strs_)
{
void
realpathize(std::vector<std::string> *strs_)
{
char *rv;
for(size_t i = 0; i < strs_->size(); i++)
{
rv = fs::realpath((*strs_)[i]);
if(rv == NULL)
continue;
(*strs_)[i] = rv;
::free(rv);
}
}
char *rv;
char resolved_path[PATH_MAX];
for(size_t i = 0; i < strs_->size(); i++)
{
rv = fs::realpath((*strs_)[i],resolved_path);
if(rv == NULL)
continue;
(*strs_)[i] = rv;
}
}

8
src/fs_remove.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <string>
#include <stdio.h>
@ -30,7 +32,11 @@ namespace fs
int
remove(const char *pathname_)
{
return ::remove(pathname_);
int rv;
rv = ::remove(pathname_);
return ::to_neg_errno(rv);
}
static

8
src/fs_rename.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <stdio.h>
@ -29,7 +31,11 @@ namespace fs
rename(const char *oldpath_,
const char *newpath_)
{
return ::rename(oldpath_,newpath_);
int rv;
rv = ::rename(oldpath_,newpath_);
return ::to_neg_errno(rv);
}
static

8
src/fs_rmdir.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <string>
#include <unistd.h>
@ -30,7 +32,11 @@ namespace fs
int
rmdir(const char *path_)
{
return ::rmdir(path_);
int rv;
rv = ::rmdir(path_);
return ::to_neg_errno(rv);
}
static

7
src/fs_sendfile_linux.icpp

@ -14,7 +14,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "errno.hpp"
#include "to_neg_errno.hpp"
#include <sys/sendfile.h>
@ -26,8 +26,11 @@ namespace fs
const int fdout,
const size_t count)
{
ssize_t rv;
off_t offset = 0;
return ::sendfile(fdout,fdin,&offset,count);
rv = ::sendfile(fdout,fdin,&offset,count);
return ::to_neg_errno(rv);
}
}

15
src/fs_sendfile_unsupported.icpp

@ -14,18 +14,17 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_sendfile.hpp"
#include "errno.hpp"
#include <sys/types.h>
namespace fs
ssize_t
fs::sendfile(const int fdin,
const int fdout,
const size_t count)
{
ssize_t
sendfile(const int fdin,
const int fdout,
const size_t count)
{
return (errno=EINVAL,-1);
}
return -EINVAL;
}

15
src/fs_setfl.cpp

@ -16,15 +16,14 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <fcntl.h>
#include "fs_setfl.hpp"
#include "fs_fcntl.hpp"
namespace fs
int
fs::setfl(const int fd_,
const mode_t mode_)
{
int
setfl(const int fd_,
const mode_t mode_)
{
return ::fcntl(fd_,F_SETFL,mode_);
}
return fs::fcntl(fd_,F_SETFL,mode_);
}

8
src/fs_stat.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <string>
#include <sys/stat.h>
@ -33,7 +35,11 @@ namespace fs
stat(const char *path_,
struct stat *st_)
{
return ::stat(path_,st_);
int rv;
rv = ::stat(path_,st_);
return ::to_neg_errno(rv);
}
static

44
src/fs_statvfs.hpp

@ -18,19 +18,12 @@
#pragma once
#include "errno.hpp"
#include "fs_close.hpp"
#include "fs_open.hpp"
#include "to_neg_errno.hpp"
#include <cstdint>
#include <string>
#include <sys/statvfs.h>
#ifndef O_PATH
# define O_PATH 0
#endif
namespace fs
{
@ -40,7 +33,11 @@ namespace fs
statvfs(const char *path_,
struct statvfs *st_)
{
return ::statvfs(path_,st_);
int rv;
rv = ::statvfs(path_,st_);
return ::to_neg_errno(rv);
}
static
@ -51,33 +48,4 @@ namespace fs
{
return fs::statvfs(path_.c_str(),st_);
}
static
inline
int
fstatvfs(const int fd_,
struct statvfs *st_)
{
return ::fstatvfs(fd_,st_);
}
static
inline
int
lstatvfs(const std::string &path_,
struct statvfs *st_)
{
int fd;
int rv;
fd = fs::open(path_,O_RDONLY|O_NOFOLLOW|O_PATH);
if(fd == -1)
return -1;
rv = fs::fstatvfs(fd,st_);
fs::close(fd);
return rv;
}
}

184
src/fs_statvfs_cache.cpp

@ -16,6 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_statvfs_cache.hpp"
#include "fs_statvfs.hpp"
#include "statvfs_util.hpp"
@ -42,104 +44,98 @@ static uint64_t g_timeout = 0;
static statvfs_cache g_cache;
static pthread_mutex_t g_cache_lock = PTHREAD_MUTEX_INITIALIZER;
namespace l
static
uint64_t
_get_time(void)
{
static
uint64_t
get_time(void)
{
uint64_t rv;
uint64_t rv;
rv = ::time(NULL);
rv = ::time(NULL);
return rv;
}
return rv;
}
namespace fs
uint64_t
fs::statvfs_cache_timeout(void)
{
uint64_t
statvfs_cache_timeout(void)
{
return g_timeout;
}
void
statvfs_cache_timeout(const uint64_t timeout_)
{
g_timeout = timeout_;
}
int
statvfs_cache(const char *path_,
struct statvfs *st_)
{
int rv;
Element *e;
uint64_t now;
if(g_timeout == 0)
return fs::statvfs(path_,st_);
rv = 0;
now = l::get_time();
mutex_lock(&g_cache_lock);
e = &g_cache[path_];
if((now - e->time) > g_timeout)
{
e->time = now;
rv = fs::statvfs(path_,&e->st);
}
*st_ = e->st;
mutex_unlock(&g_cache_lock);
return rv;
}
int
statvfs_cache_readonly(const std::string &path_,
bool *readonly_)
{
int rv;
struct statvfs st;
rv = fs::statvfs_cache(path_.c_str(),&st);
if(rv == 0)
*readonly_ = StatVFS::readonly(st);
return rv;
}
int
statvfs_cache_spaceavail(const std::string &path_,
uint64_t *spaceavail_)
{
int rv;
struct statvfs st;
rv = fs::statvfs_cache(path_.c_str(),&st);
if(rv == 0)
*spaceavail_ = StatVFS::spaceavail(st);
return rv;
}
int
statvfs_cache_spaceused(const std::string &path_,
uint64_t *spaceused_)
{
int rv;
struct statvfs st;
rv = fs::statvfs_cache(path_.c_str(),&st);
if(rv == 0)
*spaceused_ = StatVFS::spaceused(st);
return rv;
}
return g_timeout;
}
void
fs::statvfs_cache_timeout(const uint64_t timeout_)
{
g_timeout = timeout_;
}
int
fs::statvfs_cache(const char *path_,
struct statvfs *st_)
{
int rv;
Element *e;
uint64_t now;
if(g_timeout == 0)
return fs::statvfs(path_,st_);
rv = 0;
now = ::_get_time();
mutex_lock(&g_cache_lock);
e = &g_cache[path_];
if((now - e->time) > g_timeout)
{
e->time = now;
rv = fs::statvfs(path_,&e->st);
}
*st_ = e->st;
mutex_unlock(&g_cache_lock);
return rv;
}
int
fs::statvfs_cache_readonly(const std::string &path_,
bool *readonly_)
{
int rv;
struct statvfs st;
rv = fs::statvfs_cache(path_.c_str(),&st);
if(rv == 0)
*readonly_ = StatVFS::readonly(st);
return rv;
}
int
fs::statvfs_cache_spaceavail(const std::string &path_,
uint64_t *spaceavail_)
{
int rv;
struct statvfs st;
rv = fs::statvfs_cache(path_.c_str(),&st);
if(rv == 0)
*spaceavail_ = StatVFS::spaceavail(st);
return rv;
}
int
fs::statvfs_cache_spaceused(const std::string &path_,
uint64_t *spaceused_)
{
int rv;
struct statvfs st;
rv = fs::statvfs_cache(path_.c_str(),&st);
if(rv == 0)
*spaceused_ = StatVFS::spaceused(st);
return rv;
}

2
src/fs_statvfs_cache.hpp

@ -22,6 +22,8 @@
#include <sys/statvfs.h>
#include <string>
namespace fs
{

4
src/fs_statx.hpp

@ -1,5 +1,7 @@
#pragma once
#include "to_neg_errno.hpp"
#include "fuse_kernel.h"
#include <string>
@ -35,7 +37,7 @@ namespace fs
mask_,
(struct statx*)st_);
return ((rv == -1) ? -errno : 0);
return ::to_neg_errno(rv);
#else
return -ENOSYS;
#endif

14
src/fs_symlink.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <string>
#include <unistd.h>
@ -31,7 +33,11 @@ namespace fs
symlink(const char *target_,
const char *linkpath_)
{
return ::symlink(target_,linkpath_);
int rv;
rv = ::symlink(target_,linkpath_);
return ::to_neg_errno(rv);
}
static
@ -40,7 +46,8 @@ namespace fs
symlink(const std::string &target_,
const std::string &linkpath_)
{
return ::symlink(target_.c_str(),linkpath_.c_str());
return fs::symlink(target_.c_str(),
linkpath_.c_str());
}
static
@ -49,6 +56,7 @@ namespace fs
symlink(const char *target_,
const std::string &linkpath_)
{
return ::symlink(target_,linkpath_.c_str());
return fs::symlink(target_,
linkpath_.c_str());
}
}

8
src/fs_truncate.hpp

@ -18,6 +18,8 @@
#pragma once
#include "to_neg_errno.hpp"
#include <string>
#include <sys/types.h>
@ -32,7 +34,11 @@ namespace fs
truncate(const char *path_,
const off_t length_)
{
return ::truncate(path_,length_);
int rv;
rv = ::truncate(path_,length_);
return ::to_neg_errno(rv);
}
static

7
src/fs_umount2.hpp

@ -18,6 +18,9 @@
#pragma once
#include "errno.hpp"
#include "to_neg_errno.hpp"
#ifdef __FreeBSD__
# include <sys/param.h>
# include <sys/mount.h>
@ -27,8 +30,6 @@
# include <sys/mount.h>
#endif
#include <errno.h>
#include <string>
namespace fs
@ -44,7 +45,7 @@ namespace fs
rv = ::umount2(target_.c_str(),
flags_);
return ((rv == -1) ? -errno : rv);
return ::to_neg_errno(rv);
}
static

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save