Browse Source

Merge pull request #814 from trapexit/cleanup

general cleanup
pull/815/head
trapexit 4 years ago
committed by GitHub
parent
commit
7ff995631e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 77
      .cirrus.yml
  2. 14
      src/branch.cpp
  3. 13
      src/buildmap.hpp
  4. 8
      src/buildvector.hpp
  5. 59
      src/category.cpp
  6. 68
      src/category.hpp
  7. 1
      src/config.cpp
  8. 1
      src/config_statfsignore.hpp
  9. 156
      src/fs.cpp
  10. 43
      src/fs.hpp
  11. 8
      src/fs_acl.cpp
  12. 2
      src/fs_acl.hpp
  13. 6
      src/fs_attr.cpp
  14. 8
      src/fs_attr.hpp
  15. 12
      src/fs_attr_linux.icpp
  16. 4
      src/fs_attr_unsupported.icpp
  17. 35
      src/fs_base_fadvise.hpp
  18. 33
      src/fs_base_fallocate_posix.icpp
  19. 67
      src/fs_base_utime.hpp
  20. 313
      src/fs_base_utime_generic.hpp
  21. 50
      src/fs_clonefile.cpp
  22. 4
      src/fs_clonefile.hpp
  23. 103
      src/fs_clonepath.cpp
  24. 0
      src/fs_close.hpp
  25. 0
      src/fs_closedir.hpp
  26. 6
      src/fs_copy_file_range.cpp
  27. 53
      src/fs_copydata.cpp
  28. 29
      src/fs_copydata.hpp
  29. 2
      src/fs_copydata_copy_file_range.cpp
  30. 8
      src/fs_copydata_readwrite.cpp
  31. 55
      src/fs_cow.cpp
  32. 10
      src/fs_cow.hpp
  33. 6
      src/fs_devid.hpp
  34. 0
      src/fs_dirfd.hpp
  35. 0
      src/fs_dup.hpp
  36. 42
      src/fs_eaccess.hpp
  37. 4
      src/fs_exists.hpp
  38. 20
      src/fs_faccessat.hpp
  39. 30
      src/fs_fadvise.cpp
  40. 37
      src/fs_fadvise.hpp
  41. 12
      src/fs_fadvise_posix.icpp
  42. 8
      src/fs_fadvise_unsupported.icpp
  43. 8
      src/fs_fallocate.cpp
  44. 9
      src/fs_fallocate.hpp
  45. 7
      src/fs_fallocate_linux.icpp
  46. 47
      src/fs_fallocate_osx.icpp
  47. 17
      src/fs_fallocate_posix.icpp
  48. 29
      src/fs_fallocate_unsupported.icpp
  49. 2
      src/fs_fchmod.hpp
  50. 49
      src/fs_fchmodat.hpp
  51. 3
      src/fs_fchown.hpp
  52. 8
      src/fs_fdatasync.hpp
  53. 61
      src/fs_fgetxattr.hpp
  54. 6
      src/fs_ficlone.cpp
  55. 4
      src/fs_ficlone.hpp
  56. 2
      src/fs_ficlone_linux.icpp
  57. 2
      src/fs_file_size.cpp
  58. 44
      src/fs_findallfiles.cpp
  59. 30
      src/fs_findallfiles.hpp
  60. 3
      src/fs_findonfs.cpp
  61. 41
      src/fs_flistxattr.hpp
  62. 0
      src/fs_flock.hpp
  63. 61
      src/fs_fsetxattr.hpp
  64. 36
      src/fs_fstat.hpp
  65. 28
      src/fs_fstatat.hpp
  66. 32
      src/fs_fsync.hpp
  67. 0
      src/fs_ftruncate.hpp
  68. 51
      src/fs_futimens.hpp
  69. 33
      src/fs_futimens_freebsd_11.hpp
  70. 283
      src/fs_futimens_generic.hpp
  71. 33
      src/fs_futimens_linux.hpp
  72. 6
      src/fs_futimesat.cpp
  73. 8
      src/fs_futimesat.hpp
  74. 8
      src/fs_futimesat_generic.icpp
  75. 67
      src/fs_futimesat_osx.icpp
  76. 6
      src/fs_getdents64.cpp
  77. 27
      src/fs_getdents64.hpp
  78. 28
      src/fs_getfl.cpp
  79. 24
      src/fs_getfl.hpp
  80. 4
      src/fs_glob.cpp
  81. 4
      src/fs_glob.hpp
  82. 2
      src/fs_has_space.cpp
  83. 8
      src/fs_info.cpp
  84. 4
      src/fs_info.hpp
  85. 0
      src/fs_ioctl.hpp
  86. 30
      src/fs_lchmod.hpp
  87. 34
      src/fs_lchown.hpp
  88. 38
      src/fs_lgetxattr.hpp
  89. 0
      src/fs_link.hpp
  90. 14
      src/fs_llistxattr.hpp
  91. 0
      src/fs_lremovexattr.hpp
  92. 0
      src/fs_lseek.hpp
  93. 24
      src/fs_lsetxattr.hpp
  94. 46
      src/fs_lstat.hpp
  95. 48
      src/fs_lutimens.hpp
  96. 0
      src/fs_mkdir.hpp
  97. 0
      src/fs_mknod.hpp
  98. 8
      src/fs_mktemp.cpp
  99. 4
      src/fs_mktemp.hpp
  100. 14
      src/fs_movefile.cpp

77
.cirrus.yml

@ -6,7 +6,14 @@ freebsd_task:
ASSUME_ALWAYS_YES: yes ASSUME_ALWAYS_YES: yes
script: script:
- tools/install-build-pkgs - tools/install-build-pkgs
- gmake
- gmake -j4
#macos_task:
# osx_instance:
# image: catalina-base
# script:
# - tools/install-build-pkgs
# - gmake -j4
linux_task: linux_task:
name: "alpine:3.11" name: "alpine:3.11"
@ -56,9 +63,45 @@ linux_task:
- make rpm - make rpm
linux_task: linux_task:
name: "ubuntu:20.04"
name: "fedora:30"
container: container:
image: ubuntu:20.04
image: fedora:30
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- make
- make rpm
linux_task:
name: "fedora:31"
container:
image: fedora:31
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- make
- make rpm
linux_task:
name: "fedora:32"
container:
image: fedora:32
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- make
- make rpm
linux_task:
name: "ubuntu:14.04"
container:
image: ubuntu:14.04
cpu: 4 cpu: 4
memory: 2G memory: 2G
timeout_in: 10m timeout_in: 10m
@ -71,9 +114,9 @@ linux_task:
- mergerfs -v || true - mergerfs -v || true
linux_task: linux_task:
name: "ubuntu:19.10"
name: "ubuntu:16.04"
container: container:
image: ubuntu:19.10
image: ubuntu:16.04
cpu: 4 cpu: 4
memory: 2G memory: 2G
timeout_in: 10m timeout_in: 10m
@ -101,9 +144,9 @@ linux_task:
- mergerfs -v || true - mergerfs -v || true
linux_task: linux_task:
name: "ubuntu:16.04"
name: "ubuntu:19.10"
container: container:
image: ubuntu:16.04
image: ubuntu:19.10
cpu: 4 cpu: 4
memory: 2G memory: 2G
timeout_in: 10m timeout_in: 10m
@ -116,9 +159,9 @@ linux_task:
- mergerfs -v || true - mergerfs -v || true
linux_task: linux_task:
name: "ubuntu:14.04"
name: "ubuntu:20.04"
container: container:
image: ubuntu:14.04
image: ubuntu:20.04
cpu: 4 cpu: 4
memory: 2G memory: 2G
timeout_in: 10m timeout_in: 10m
@ -131,9 +174,9 @@ linux_task:
- mergerfs -v || true - mergerfs -v || true
linux_task: linux_task:
name: "debian:10"
name: "debian:7"
container: container:
image: debian:10
image: debian:8
cpu: 4 cpu: 4
memory: 2G memory: 2G
timeout_in: 10m timeout_in: 10m
@ -146,9 +189,9 @@ linux_task:
- mergerfs -v || true - mergerfs -v || true
linux_task: linux_task:
name: "debian:9"
name: "debian:8"
container: container:
image: debian:9
image: debian:8
cpu: 4 cpu: 4
memory: 2G memory: 2G
timeout_in: 10m timeout_in: 10m
@ -161,9 +204,9 @@ linux_task:
- mergerfs -v || true - mergerfs -v || true
linux_task: linux_task:
name: "debian:8"
name: "debian:9"
container: container:
image: debian:8
image: debian:9
cpu: 4 cpu: 4
memory: 2G memory: 2G
timeout_in: 10m timeout_in: 10m
@ -176,9 +219,9 @@ linux_task:
- mergerfs -v || true - mergerfs -v || true
linux_task: linux_task:
name: "debian:7"
name: "debian:10"
container: container:
image: debian:8
image: debian:10
cpu: 4 cpu: 4
memory: 2G memory: 2G
timeout_in: 10m timeout_in: 10m

14
src/branch.cpp

@ -18,8 +18,8 @@
#include "branch.hpp" #include "branch.hpp"
#include "ef.hpp" #include "ef.hpp"
#include "fs.hpp"
#include "fs_glob.hpp" #include "fs_glob.hpp"
#include "fs_realpathize.hpp"
#include "str.hpp" #include "str.hpp"
#include <string> #include <string>
@ -91,8 +91,8 @@ parse(const string &str_,
else else
branch.mode = Branch::RW; branch.mode = Branch::RW;
fs::glob(str,globbed);
fs::realpathize(globbed);
fs::glob(str,&globbed);
fs::realpathize(&globbed);
for(size_t i = 0; i < globbed.size(); i++) for(size_t i = 0; i < globbed.size(); i++)
{ {
branch.path = globbed[i]; branch.path = globbed[i];
@ -109,7 +109,7 @@ set(Branches &branches_,
branches_.clear(); branches_.clear();
str::split(paths,str_,':');
str::split(str_,':',&paths);
for(size_t i = 0; i < paths.size(); i++) for(size_t i = 0; i < paths.size(); i++)
{ {
@ -130,7 +130,7 @@ add_begin(Branches &branches_,
{ {
vector<string> paths; vector<string> paths;
str::split(paths,str_,':');
str::split(str_,':',&paths);
for(size_t i = 0; i < paths.size(); i++) for(size_t i = 0; i < paths.size(); i++)
{ {
@ -151,7 +151,7 @@ add_end(Branches &branches_,
{ {
vector<string> paths; vector<string> paths;
str::split(paths,str_,':');
str::split(str_,':',&paths);
for(size_t i = 0; i < paths.size(); i++) for(size_t i = 0; i < paths.size(); i++)
{ {
@ -186,7 +186,7 @@ erase_fnmatch(Branches &branches_,
{ {
vector<string> patterns; vector<string> patterns;
str::split(patterns,str_,':');
str::split(str_,':',&patterns);
for(Branches::iterator i = branches_.begin(); for(Branches::iterator i = branches_.begin();
i != branches_.end();) i != branches_.end();)

13
src/buildmap.hpp

@ -17,21 +17,22 @@
#pragma once #pragma once
#include <algorithm> #include <algorithm>
#include <map>
template<typename K,typename V> template<typename K,typename V>
class buildmap class buildmap
{ {
public: public:
buildmap(const K &key,
const V &val)
buildmap(const K &key_,
const V &val_)
{ {
_map.insert(std::make_pair(key,val));
_map.insert(std::make_pair(key_,val_));
} }
buildmap<K,V> &operator()(const K &key,
const V &val)
buildmap<K,V> &operator()(const K &key_,
const V &val_)
{ {
_map.insert(std::make_pair(key,val));
_map.insert(std::make_pair(key_,val_));
return *this; return *this;
} }

8
src/buildvector.hpp

@ -23,14 +23,14 @@ template<typename V, bool SORT = false>
class buildvector class buildvector
{ {
public: public:
buildvector(const V &val)
buildvector(const V &val_)
{ {
_vector.push_back(val);
_vector.push_back(val_);
} }
buildvector<V,SORT> &operator()(const V &val)
buildvector<V,SORT> &operator()(const V &val_)
{ {
_vector.push_back(val);
_vector.push_back(val_);
return *this; return *this;
} }

59
src/category.cpp

@ -1,59 +0,0 @@
/*
Copyright (c) 2016, 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 <string>
#include <vector>
#include "category.hpp"
#include "buildvector.hpp"
#define CATEGORY(X) Category(Category::Enum::X,#X)
const std::vector<Category> Category::_categories_ =
buildvector<Category,true>
(CATEGORY(invalid))
(CATEGORY(action))
(CATEGORY(create))
(CATEGORY(search));
const Category * const Category::categories = &_categories_[1];
const Category &Category::invalid = Category::categories[Category::Enum::invalid];
const Category &Category::action = Category::categories[Category::Enum::action];
const Category &Category::create = Category::categories[Category::Enum::create];
const Category &Category::search = Category::categories[Category::Enum::search];
const Category&
Category::find(const std::string &str)
{
for(int i = Enum::BEGIN; i != Enum::END; ++i)
{
if(categories[i] == str)
return categories[i];
}
return invalid;
}
const Category&
Category::find(const Category::Enum::Type i)
{
if(i >= Category::Enum::BEGIN &&
i < Category::Enum::END)
return categories[i];
return invalid;
}

68
src/category.hpp

@ -16,69 +16,9 @@
#pragma once #pragma once
#include <string>
#include <vector>
class Category
{
public:
struct Enum
enum class Category
{ {
enum Type
{
invalid = -1,
BEGIN = 0,
action = BEGIN,
create,
search,
END
};
ACTION,
CREATE,
SEARCH
}; };
private:
Enum::Type _enum;
std::string _str;
public:
Category()
: _enum(invalid),
_str(invalid)
{
}
Category(const Enum::Type enum_,
const std::string &str_)
: _enum(enum_),
_str(str_)
{
}
public:
operator const Enum::Type() const { return _enum; }
operator const std::string&() const { return _str; }
operator const Category*() const { return this; }
bool operator==(const std::string &str_) const
{ return _str == str_; }
bool operator==(const Enum::Type enum_) const
{ return _enum == enum_; }
bool operator!=(const Category &r) const
{ return _enum != r._enum; }
bool operator<(const Category &r) const
{ return _enum < r._enum; }
public:
static const Category &find(const std::string&);
static const Category &find(const Enum::Type);
public:
static const std::vector<Category> _categories_;
static const Category * const categories;
static const Category &invalid;
static const Category &action;
static const Category &create;
static const Category &search;
};

1
src/config.cpp

@ -18,7 +18,6 @@
#include "ef.hpp" #include "ef.hpp"
#include "errno.hpp" #include "errno.hpp"
#include "from_string.hpp" #include "from_string.hpp"
#include "fs.hpp"
#include "num.hpp" #include "num.hpp"
#include "rwlock.hpp" #include "rwlock.hpp"
#include "to_string.hpp" #include "to_string.hpp"

1
src/config_statfsignore.hpp

@ -26,4 +26,5 @@ enum class StatFSIgnoreEnum
RO, RO,
NC NC
}; };
typedef Enum<StatFSIgnoreEnum> StatFSIgnore; typedef Enum<StatFSIgnoreEnum> StatFSIgnore;

156
src/fs.cpp

@ -1,156 +0,0 @@
/*
Copyright (c) 2016, 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 <string>
#include <vector>
#include <fcntl.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include "errno.hpp"
#include "fs_attr.hpp"
#include "fs_base_realpath.hpp"
#include "fs_base_stat.hpp"
#include "fs_exists.hpp"
#include "fs_path.hpp"
#include "fs_statvfs_cache.hpp"
#include "fs_xattr.hpp"
#include "str.hpp"
using std::string;
using std::vector;
namespace fs
{
void
findallfiles(const vector<string> &basepaths,
const char *fusepath,
vector<string> &paths)
{
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);
}
}
int
findonfs(const vector<string> &basepaths,
const string &fusepath,
const int fd,
string &basepath)
{
int rv;
dev_t dev;
string fullpath;
struct stat st;
rv = fs::fstat(fd,&st);
if(rv == -1)
return -1;
dev = st.st_dev;
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{
fullpath = fs::path::make(basepaths[i],fusepath);
rv = fs::lstat(fullpath,&st);
if(rv == -1)
continue;
if(st.st_dev != dev)
continue;
basepath = basepaths[i];
return 0;
}
return (errno=ENOENT,-1);
}
void
realpathize(vector<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);
}
}
int
getfl(const int fd)
{
return ::fcntl(fd,F_GETFL,0);
}
int
setfl(const int fd,
const mode_t mode)
{
return ::fcntl(fd,F_SETFL,mode);
}
int
mfs(const vector<string> &basepaths,
const uint64_t minfreespace,
string &path)
{
int rv;
uint64_t mfs;
uint64_t spaceavail;
const string *mfsbasepath;
mfs = 0;
mfsbasepath = NULL;
for(size_t i = 0, ei = basepaths.size(); i != ei; i++)
{
rv = fs::statvfs_cache_spaceavail(basepaths[i],&spaceavail);
if(rv == -1)
continue;
if(spaceavail < minfreespace)
continue;
if(spaceavail <= mfs)
continue;
mfs = spaceavail;
mfsbasepath = &basepaths[i];
}
if(mfsbasepath == NULL)
return (errno=ENOENT,-1);
path = *mfsbasepath;
return 0;
}
};

43
src/fs.hpp

@ -1,43 +0,0 @@
/*
Copyright (c) 2016, 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 <string>
#include <vector>
#include <fcntl.h>
#include <stdint.h>
namespace fs
{
using std::string;
using std::vector;
void findallfiles(const vector<string> &basepaths_,
const char *fusepath_,
vector<string> &paths_);
void realpathize(vector<string> &strs_);
int getfl(const int fd_);
int setfl(const int fd_,
const mode_t mode_);
int mfs(const vector<string> &srcs_,
const uint64_t minfreespace_,
string &path_);
}

8
src/fs_acl.cpp

@ -16,11 +16,11 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <string>
#include "fs_base_getxattr.hpp"
#include "fs_lgetxattr.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include <string>
const char POSIX_ACL_DEFAULT_XATTR[] = "system.posix_acl_default"; const char POSIX_ACL_DEFAULT_XATTR[] = "system.posix_acl_default";
namespace fs namespace fs
@ -31,7 +31,7 @@ namespace fs
dir_has_defaults(const std::string &fullpath_) dir_has_defaults(const std::string &fullpath_)
{ {
int rv; int rv;
std::string dirpath;
std::string dirpath;
dirpath = fs::path::dirname(fullpath_); dirpath = fs::path::dirname(fullpath_);

2
src/fs_acl.hpp

@ -25,6 +25,6 @@ namespace fs
namespace acl namespace acl
{ {
bool bool
dir_has_defaults(const std::string &fullpath_);
dir_has_defaults(const std::string &fullpath);
} }
} }

6
src/fs_attr.cpp

@ -15,7 +15,9 @@
*/ */
#ifdef __linux__ #ifdef __linux__
# include "fs_attr_linux.icpp"
#warning "using fs_attr_linux.icpp"
#include "fs_attr_linux.icpp"
#else #else
# include "fs_attr_unsupported.icpp"
#warning "using fs_attr_unsupported.icpp"
#include "fs_attr_unsupported.icpp"
#endif #endif

8
src/fs_attr.hpp

@ -22,9 +22,9 @@ namespace fs
{ {
namespace attr namespace attr
{ {
int copy(const int fdin_,
const int fdout_);
int copy(const std::string &from_,
const std::string &to_);
int copy(const int fdin,
const int fdout);
int copy(const std::string &from,
const std::string &to);
} }
} }

12
src/fs_attr_linux.icpp

@ -14,15 +14,15 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <fcntl.h>
#include <linux/fs.h>
#include "errno.hpp"
#include "fs_close.hpp"
#include "fs_open.hpp"
#include "fs_ioctl.hpp"
#include <string> #include <string>
#include "errno.hpp"
#include "fs_base_close.hpp"
#include "fs_base_open.hpp"
#include "fs_base_ioctl.hpp"
#include <fcntl.h>
#include <linux/fs.h>
using std::string; using std::string;

4
src/fs_attr_unsupported.icpp

@ -14,10 +14,10 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <string>
#include "errno.hpp" #include "errno.hpp"
#include <string>
namespace fs namespace fs
{ {
namespace attr namespace attr

35
src/fs_base_fadvise.hpp

@ -1,35 +0,0 @@
/*
Copyright (c) 2016, 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
namespace fs
{
int
fadvise_dontneed(const int fd_,
const off_t offset_ = 0,
const off_t len_ = 0);
int
fadvise_willneed(const int fd_,
const off_t offset_ = 0,
const off_t len_ = 0);
int
fadvise_sequential(const int fd_,
const off_t offset_ = 0,
const off_t len_ = 0);
}

33
src/fs_base_fallocate_posix.icpp

@ -1,33 +0,0 @@
/*
Copyright (c) 2016, 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 <fcntl.h>
#include "errno.hpp"
namespace fs
{
int
fallocate(const int fd,
const int mode,
const off_t offset,
const off_t len)
{
return (mode ?
(errno=EOPNOTSUPP,-1) :
(::posix_fallocate(fd,offset,len)));
}
}

67
src/fs_base_utime.hpp

@ -1,67 +0,0 @@
/*
Copyright (c) 2016, 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
#ifdef __linux__
# include "fs_base_utime_utimensat.hpp"
#elif __FreeBSD__ >= 11
# include "fs_base_utime_utimensat.hpp"
#else
# include "fs_base_utime_generic.hpp"
#endif
#include "fs_base_stat.hpp"
namespace fs
{
static
inline
int
utime(const std::string &path_,
const struct stat &st_)
{
struct timespec times[2];
times[0] = *fs::stat_atime(&st_);
times[1] = *fs::stat_mtime(&st_);
return fs::utime(AT_FDCWD,path_,times,0);
}
static
inline
int
futime(const int fd_,
const struct stat &st_)
{
struct timespec ts[2];
ts[0] = *fs::stat_atime(&st_);
ts[1] = *fs::stat_mtime(&st_);
return fs::futimens(fd_,ts);
}
static
inline
int
lutime(const std::string &path_,
const struct timespec times_[2])
{
return fs::utime(AT_FDCWD,path_,times_,AT_SYMLINK_NOFOLLOW);
}
}

313
src/fs_base_utime_generic.hpp

@ -1,313 +0,0 @@
/*
ISC License
Copyright (c) 2016, 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_base_futimesat.hpp"
#include "fs_base_stat.hpp"
#include <string>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#ifndef UTIME_NOW
# define UTIME_NOW ((1l << 30) - 1l)
#endif
#ifndef UTIME_OMIT
# define UTIME_OMIT ((1l << 30) - 2l)
#endif
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] == '/')));
}
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
_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) &&
(_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
_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
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(!_any_timespec_is_utime_omit(ts_))
return 0;
rv = ::fstatat(dirfd,path.c_str(),&st,flags);
if(rv == -1)
return -1;
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);
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;
if(!_any_timespec_is_utime_omit(ts_))
return 0;
rv = ::fstat(fd,&st);
if(rv == -1)
return -1;
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);
return 0;
}
static
inline
int
_set_utime_now_to_now(const struct timespec ts_[2],
struct timeval tv[2])
{
int rv;
struct timeval now;
if(_any_timespec_is_utime_now(ts_))
return 0;
rv = ::gettimeofday(&now,NULL);
if(rv == -1)
return -1;
if(ts_[0].tv_nsec == UTIME_NOW)
tv[0] = now;
if(ts_[1].tv_nsec == UTIME_NOW)
tv[1] = now;
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;
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]);
rv = _set_utime_omit_to_current_value(dirfd,path,ts_,tv,flags);
if(rv == -1)
return -1;
rv = _set_utime_now_to_now(ts_,tv);
if(rv == -1)
return -1;
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;
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]);
rv = _set_utime_omit_to_current_value(fd,ts_,tv);
if(rv == -1)
return -1;
rv = _set_utime_now_to_now(ts_,tv);
if(rv == -1)
return -1;
return (tvp=tv,0);
}
namespace fs
{
static
inline
int
utime(const int dirfd,
const std::string &path,
const struct timespec ts_[2],
const int flags)
{
int rv;
struct timeval tv[2];
struct timeval *tvp;
if(_flags_invalid(flags))
return (errno=EINVAL,-1);
if(_timespec_invalid(ts_))
return (errno=EINVAL,-1);
if(_should_ignore(ts_))
return 0;
rv = _convert_timespec_to_timeval(dirfd,path,ts_,tv,tvp,flags);
if(rv == -1)
return -1;
if((flags & AT_SYMLINK_NOFOLLOW) == 0)
return fs::futimesat(dirfd,path.c_str(),tvp);
if(_can_call_lutimes(dirfd,path,flags))
return ::lutimes(path.c_str(),tvp);
return (errno=ENOTSUP,-1);
}
static
inline
int
futimens(const int fd_,
const struct timespec ts_[2])
{
int rv;
struct timeval tv[2];
struct timeval *tvp;
if(_timespec_invalid(ts_))
return (errno=EINVAL,-1);
if(_should_ignore(ts_))
return 0;
rv = _convert_timespec_to_timeval(fd_,ts_,tv,tvp);
if(rv == -1)
return -1;
return ::futimes(fd_,tvp);
}
}

50
src/fs_clonefile.cpp

@ -14,52 +14,16 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "errno.hpp"
#include "fs_fstat.hpp"
#include "fs_copydata.hpp"
#include "fs_attr.hpp" #include "fs_attr.hpp"
#include "fs_base_chmod.hpp"
#include "fs_base_chown.hpp"
#include "fs_base_fadvise.hpp"
#include "fs_base_fallocate.hpp"
#include "fs_base_fchmod.hpp"
#include "fs_base_fchown.hpp"
#include "fs_base_ftruncate.hpp"
#include "fs_base_stat.hpp"
#include "fs_base_utime.hpp"
#include "fs_copy_file_range.hpp"
#include "fs_copydata_copy_file_range.hpp"
#include "fs_copydata_readwrite.hpp"
#include "fs_ficlone.hpp"
#include "fs_sendfile.hpp"
#include "fs_xattr.hpp" #include "fs_xattr.hpp"
#include "fs_fchown.hpp"
#include "fs_fchmod.hpp"
#include "fs_futimens.hpp"
namespace l namespace l
{ {
static
int
copydata(const int src_fd_,
const int dst_fd_,
const size_t count_)
{
int rv;
rv = fs::ftruncate(dst_fd_,count_);
if(rv == -1)
return -1;
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_);
if(rv != -1)
return rv;
return fs::copydata_readwrite(src_fd_,dst_fd_);
}
static static
bool bool
ignorable_error(const int err_) ignorable_error(const int err_)
@ -91,7 +55,7 @@ namespace fs
if(rv == -1) if(rv == -1)
return -1; return -1;
rv = l::copydata(src_fd_,dst_fd_,src_st.st_size);
rv = fs::copydata(src_fd_,dst_fd_,src_st.st_size);
if(rv == -1) if(rv == -1)
return -1; return -1;
@ -111,7 +75,7 @@ namespace fs
if(rv == -1) if(rv == -1)
return -1; return -1;
rv = fs::futime(dst_fd_,src_st);
rv = fs::futimens(dst_fd_,src_st);
if(rv == -1) if(rv == -1)
return -1; return -1;

4
src/fs_clonefile.hpp

@ -19,6 +19,6 @@
namespace fs namespace fs
{ {
int int
clonefile(const int src_fd_,
const int dst_fd_);
clonefile(const int src_fd,
const int dst_fd);
} }

103
src/fs_clonepath.cpp

@ -18,33 +18,35 @@
#include "errno.h" #include "errno.h"
#include "fs_attr.hpp" #include "fs_attr.hpp"
#include "fs_base_chmod.hpp"
#include "fs_base_chown.hpp"
#include "fs_base_mkdir.hpp"
#include "fs_base_stat.hpp"
#include "fs_base_utime.hpp"
#include "fs_clonepath.hpp" #include "fs_clonepath.hpp"
#include "fs_lchown.hpp"
#include "fs_lstat.hpp"
#include "fs_lutimens.hpp"
#include "fs_mkdir.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "fs_xattr.hpp" #include "fs_xattr.hpp"
#include "ugid.hpp" #include "ugid.hpp"
using std::string; using std::string;
static
bool
ignorable_error(const int err)
namespace l
{ {
switch(err)
{
case ENOTTY:
case ENOTSUP:
static
bool
ignorable_error(const int err_)
{
switch(err_)
{
case ENOTTY:
case ENOTSUP:
#if ENOTSUP != EOPNOTSUPP #if ENOTSUP != EOPNOTSUPP
case EOPNOTSUPP:
case EOPNOTSUPP:
#endif #endif
return true;
}
return true;
}
return false;
return false;
}
} }
namespace fs namespace fs
@ -54,12 +56,12 @@ namespace fs
The directories which already exist are left alone. The directories which already exist are left alone.
The new directories have metadata set to match the original if The new directories have metadata set to match the original if
possible. Optionally ignore errors on metadata copies. possible. Optionally ignore errors on metadata copies.
*/
*/
int int
clonepath(const string &fromsrc,
const string &tosrc,
const char *relative,
const bool return_metadata_errors)
clonepath(const string &fromsrc_,
const string &tosrc_,
const char *relative_,
const bool return_metadata_errors_)
{ {
int rv; int rv;
struct stat st; struct stat st;
@ -67,25 +69,25 @@ namespace fs
string frompath; string frompath;
string dirname; string dirname;
if((relative == NULL) || (relative[0] == '\0'))
if((relative_ == NULL) || (relative_[0] == '\0'))
return 0; return 0;
dirname = fs::path::dirname(relative);
dirname = fs::path::dirname(relative_);
if(!dirname.empty()) if(!dirname.empty())
{ {
rv = fs::clonepath(fromsrc,tosrc,dirname);
rv = fs::clonepath(fromsrc_,tosrc_,dirname,return_metadata_errors_);
if(rv == -1) if(rv == -1)
return -1; return -1;
} }
frompath = fs::path::make(fromsrc,relative);
rv = fs::stat(frompath,&st);
frompath = fs::path::make(fromsrc_,relative_);
rv = fs::lstat(frompath,&st);
if(rv == -1) if(rv == -1)
return -1; return -1;
else if(!S_ISDIR(st.st_mode)) else if(!S_ISDIR(st.st_mode))
return (errno=ENOTDIR,-1); return (errno=ENOTDIR,-1);
topath = fs::path::make(tosrc,relative);
topath = fs::path::make(tosrc_,relative_);
rv = fs::mkdir(topath,st.st_mode); rv = fs::mkdir(topath,st.st_mode);
if(rv == -1) if(rv == -1)
{ {
@ -97,58 +99,61 @@ namespace fs
// it may not support it... it's fine... // it may not support it... it's fine...
rv = fs::attr::copy(frompath,topath); rv = fs::attr::copy(frompath,topath);
if(return_metadata_errors && (rv == -1) && !ignorable_error(errno))
if(return_metadata_errors_ && (rv == -1) && !l::ignorable_error(errno))
return -1; return -1;
// it may not support it... it's fine... // it may not support it... it's fine...
rv = fs::xattr::copy(frompath,topath); rv = fs::xattr::copy(frompath,topath);
if(return_metadata_errors && (rv == -1) && !ignorable_error(errno))
if(return_metadata_errors_ && (rv == -1) && !l::ignorable_error(errno))
return -1; return -1;
rv = fs::lchown_check_on_error(topath,st); rv = fs::lchown_check_on_error(topath,st);
if(return_metadata_errors && (rv == -1))
if(return_metadata_errors_ && (rv == -1))
return -1; return -1;
rv = fs::utime(topath,st);
if(return_metadata_errors && (rv == -1))
rv = fs::lutimens(topath,st);
if(return_metadata_errors_ && (rv == -1))
return -1; return -1;
return 0; return 0;
} }
int int
clonepath(const string &from,
const string &to,
const string &relative,
const bool return_metadata_errors)
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);
return fs::clonepath(from_,
to_,
relative_.c_str(),
return_metadata_errors_);
} }
int int
clonepath_as_root(const string &from,
const string &to,
const char *relative,
const bool return_metadata_errors)
clonepath_as_root(const string &from_,
const string &to_,
const char *relative_,
const bool return_metadata_errors_)
{ {
if((relative == NULL) || (relative[0] == '\0'))
if((relative_ == NULL) || (relative_[0] == '\0'))
return 0; return 0;
if(from == to)
if(from_ == to_)
return 0; return 0;
{ {
const ugid::SetRootGuard ugidGuard; const ugid::SetRootGuard ugidGuard;
return fs::clonepath(from,to,relative,return_metadata_errors);
return fs::clonepath(from_,to_,relative_,return_metadata_errors_);
} }
} }
int int
clonepath_as_root(const string &from,
const string &to,
const string &relative,
const bool return_metadata_errors)
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);
return fs::clonepath_as_root(from_,to_,relative_.c_str(),return_metadata_errors_);
} }
} }

0
src/fs_base_close.hpp → src/fs_close.hpp

0
src/fs_base_closedir.hpp → src/fs_closedir.hpp

6
src/fs_copy_file_range.cpp

@ -17,7 +17,9 @@
*/ */
#ifdef __linux__ #ifdef __linux__
# include "fs_copy_file_range_linux.icpp"
#warning "using fs_copy_file_range_linux.icpp"
#include "fs_copy_file_range_linux.icpp"
#else #else
# include "fs_copy_file_range_unsupported.icpp"
#warning "using fs_copy_file_range_unsupported.icpp"
#include "fs_copy_file_range_unsupported.icpp"
#endif #endif

53
src/fs_copydata.cpp

@ -0,0 +1,53 @@
/*
ISC License
Copyright (c) 2020, 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_copydata_copy_file_range.hpp"
#include "fs_copydata_readwrite.hpp"
#include "fs_fadvise.hpp"
#include "fs_ficlone.hpp"
#include "fs_ftruncate.hpp"
#include <stddef.h>
namespace fs
{
int
copydata(const int src_fd_,
const int dst_fd_,
const size_t count_)
{
int rv;
rv = fs::ftruncate(dst_fd_,count_);
if(rv == -1)
return -1;
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_);
if(rv != -1)
return rv;
return fs::copydata_readwrite(src_fd_,dst_fd_);
}
}

29
src/fs_copydata.hpp

@ -0,0 +1,29 @@
/*
ISC License
Copyright (c) 2020, 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 <stddef.h>
namespace fs
{
int
copydata(const int src_fd,
const int dst_fd,
const size_t count);
}

2
src/fs_copydata_copy_file_range.cpp

@ -15,8 +15,8 @@
*/ */
#include "errno.hpp" #include "errno.hpp"
#include "fs_base_stat.hpp"
#include "fs_copy_file_range.hpp" #include "fs_copy_file_range.hpp"
#include "fs_fstat.hpp"
#include <stdint.h> #include <stdint.h>

8
src/fs_copydata_readwrite.cpp

@ -15,10 +15,10 @@
*/ */
#include "errno.hpp" #include "errno.hpp"
#include "fs_base_stat.hpp"
#include "fs_base_lseek.hpp"
#include "fs_base_read.hpp"
#include "fs_base_write.hpp"
#include "fs_fstat.hpp"
#include "fs_lseek.hpp"
#include "fs_read.hpp"
#include "fs_write.hpp"
#include <vector> #include <vector>

55
src/fs_cow.cpp

@ -16,18 +16,17 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "errno.hpp"
#include "fs_clonefile.hpp" #include "fs_clonefile.hpp"
#include "fs_close.hpp"
#include "fs_lstat.hpp"
#include "fs_mktemp.hpp" #include "fs_mktemp.hpp"
#include "fs_base_close.hpp"
#include "fs_base_open.hpp"
#include "fs_base_rename.hpp"
#include "fs_base_stat.hpp"
#include "fs_base_unlink.hpp"
#include "fs_open.hpp"
#include "fs_rename.hpp"
#include "fs_unlink.hpp"
#include <string> #include <string>
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
@ -35,27 +34,29 @@
using std::string; using std::string;
static
int
cleanup_on_error(const int src_fd_,
const int dst_fd_ = -1,
const string &dst_fullpath_ = string())
namespace l
{ {
int error = errno;
static
int
cleanup_on_error(const int src_fd_,
const int dst_fd_ = -1,
const string &dst_fullpath_ = string())
{
int error = errno;
if(src_fd_ >= 0)
fs::close(src_fd_);
if(dst_fd_ >= 0)
fs::close(dst_fd_);
if(!dst_fullpath_.empty())
fs::unlink(dst_fullpath_);
if(src_fd_ >= 0)
fs::close(src_fd_);
if(dst_fd_ >= 0)
fs::close(dst_fd_);
if(!dst_fullpath_.empty())
fs::unlink(dst_fullpath_);
errno = error;
errno = error;
return -1;
return -1;
}
} }
namespace fs namespace fs
{ {
namespace cow namespace cow
@ -91,7 +92,7 @@ namespace fs
int rv; int rv;
struct stat st; struct stat st;
if(!is_eligible(flags_))
if(!fs::cow::is_eligible(flags_))
return false; return false;
rv = fs::lstat(fullpath_,&st); rv = fs::lstat(fullpath_,&st);
@ -115,17 +116,17 @@ namespace fs
dst_fullpath = src_fullpath_; dst_fullpath = src_fullpath_;
dst_fd = fs::mktemp(dst_fullpath,O_WRONLY);
dst_fd = fs::mktemp(&dst_fullpath,O_WRONLY);
if(dst_fd == -1) if(dst_fd == -1)
return cleanup_on_error(src_fd);
return l::cleanup_on_error(src_fd);
rv = fs::clonefile(src_fd,dst_fd); rv = fs::clonefile(src_fd,dst_fd);
if(rv == -1) if(rv == -1)
return cleanup_on_error(src_fd,dst_fd,dst_fullpath);
return l::cleanup_on_error(src_fd,dst_fd,dst_fullpath);
rv = fs::rename(dst_fullpath,src_fullpath_); rv = fs::rename(dst_fullpath,src_fullpath_);
if(rv == -1) if(rv == -1)
return cleanup_on_error(src_fd,dst_fd,dst_fullpath);
return l::cleanup_on_error(src_fd,dst_fd,dst_fullpath);
fs::close(src_fd); fs::close(src_fd);
fs::close(dst_fd); fs::close(dst_fd);

10
src/fs_cow.hpp

@ -25,12 +25,12 @@ namespace fs
{ {
namespace cow namespace cow
{ {
bool is_eligible(const int flags_);
bool is_eligible(const struct stat &st_);
bool is_eligible(const int flags_, const struct stat &st_);
bool is_eligible(const int flags);
bool is_eligible(const struct stat &st);
bool is_eligible(const int flags, const struct stat &st);
bool is_eligible(const char *fullpath_, const int flags_);
bool is_eligible(const char *fullpath, const int flags);
int break_link(const char *fullpath_);
int break_link(const char *fullpath);
} }
} }

6
src/fs_devid.hpp

@ -18,9 +18,7 @@
#pragma once #pragma once
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "fs_fstat.hpp"
namespace fs namespace fs
{ {
@ -32,7 +30,7 @@ namespace fs
int rv; int rv;
struct stat st; struct stat st;
rv = ::fstat(fd_,&st);
rv = fs::fstat(fd_,&st);
if(rv == -1) if(rv == -1)
return -1; return -1;

0
src/fs_base_dirfd.hpp → src/fs_dirfd.hpp

0
src/fs_base_dup.hpp → src/fs_dup.hpp

42
src/fs_eaccess.hpp

@ -0,0 +1,42 @@
/*
ISC License
Copyright (c) 2020, 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_faccessat.hpp"
namespace fs
{
static
inline
int
eaccess(const char *path_,
const int mode_)
{
return fs::faccessat(AT_FDCWD,path_,mode_,AT_EACCESS);
}
static
inline
int
eaccess(const std::string &path_,
const int mode_)
{
return fs::eaccess(path_.c_str(),mode_);
}
}

4
src/fs_exists.hpp

@ -18,7 +18,7 @@
#pragma once #pragma once
#include "fs_base_stat.hpp"
#include "fs_lstat.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include <string> #include <string>
@ -70,7 +70,7 @@ namespace fs
{ {
std::string fullpath; std::string fullpath;
fullpath = fs::path::make(&basepath_,relpath_);
fullpath = fs::path::make(basepath_,relpath_);
return fs::exists(fullpath,st_); return fs::exists(fullpath,st_);
} }

20
src/fs_base_utime_utimensat.hpp → src/fs_faccessat.hpp

@ -21,27 +21,29 @@
#include <string> #include <string>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
namespace fs namespace fs
{ {
static static
inline inline
int int
utime(const int dirfd,
const std::string &path,
const struct timespec times[2],
const int flags)
faccessat(const int dirfd_,
const char *path_,
const int mode_,
const int flags_)
{ {
return ::utimensat(dirfd,path.c_str(),times,flags);
return ::faccessat(dirfd_,path_,mode_,flags_);
} }
static static
inline inline
int int
futimens(const int fd_,
const struct timespec ts_[2])
faccessat(const int dirfd_,
const std::string &path_,
const int mode_,
const int flags_)
{ {
return ::futimens(fd_,ts_);
return fs::faccessat(dirfd_,path_.c_str(),mode_,flags_);
} }
} }

30
src/fs_base_fadvise.cpp → src/fs_fadvise.cpp

@ -17,9 +17,11 @@
#include <fcntl.h> #include <fcntl.h>
#if _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L #if _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L
# include "fs_base_fadvise_posix.icpp"
#warning "using fs_fadvise_posix.icpp"
#include "fs_fadvise_posix.icpp"
#else #else
# include "fs_base_fadvise_unsupported.icpp"
#warning "using fs_fadvise_unsupported.icpp"
#include "fs_fadvise_unsupported.icpp"
#endif #endif
#ifndef POSIX_FADV_NORMAL #ifndef POSIX_FADV_NORMAL
@ -49,26 +51,26 @@
namespace fs namespace fs
{ {
int int
fadvise_dontneed(const int fd,
const off_t offset,
const off_t len)
fadvise_dontneed(const int fd_,
const off_t offset_,
const off_t len_)
{ {
return fs::fadvise(fd,offset,len,POSIX_FADV_DONTNEED);
return fs::fadvise(fd_,offset_,len_,POSIX_FADV_DONTNEED);
} }
int int
fadvise_willneed(const int fd,
const off_t offset,
const off_t len)
fadvise_willneed(const int fd_,
const off_t offset_,
const off_t len_)
{ {
return fs::fadvise(fd,offset,len,POSIX_FADV_WILLNEED);
return fs::fadvise(fd_,offset_,len_,POSIX_FADV_WILLNEED);
} }
int int
fadvise_sequential(const int fd,
const off_t offset,
const off_t len)
fadvise_sequential(const int fd_,
const off_t offset_,
const off_t len_)
{ {
return fs::fadvise(fd,offset,len,POSIX_FADV_SEQUENTIAL);
return fs::fadvise(fd_,offset_,len_,POSIX_FADV_SEQUENTIAL);
} }
} }

37
src/fs_fadvise.hpp

@ -0,0 +1,37 @@
/*
Copyright (c) 2016, 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 <sys/types.h>
namespace fs
{
int
fadvise_dontneed(const int fd,
const off_t offset = 0,
const off_t len = 0);
int
fadvise_willneed(const int fd,
const off_t offset = 0,
const off_t len = 0);
int
fadvise_sequential(const int fd,
const off_t offset = 0,
const off_t len = 0);
}

12
src/fs_base_fadvise_posix.icpp → src/fs_fadvise_posix.icpp

@ -16,17 +16,15 @@
#include <fcntl.h> #include <fcntl.h>
#include "errno.hpp"
namespace fs namespace fs
{ {
static static
int int
fadvise(const int fd,
const off_t offset,
const off_t len,
const int advice)
fadvise(const int fd_,
const off_t offset_,
const off_t len_,
const int advice_)
{ {
return ::posix_fadvise(fd,offset,len,advice);
return ::posix_fadvise(fd_,offset_,len_,advice_);
} }
} }

8
src/fs_base_fadvise_unsupported.icpp → src/fs_fadvise_unsupported.icpp

@ -20,10 +20,10 @@ namespace fs
{ {
static static
int int
fadvise(const int fd,
const off_t offset,
const off_t len,
const int advice)
fadvise(const int fd_,
const off_t offset_,
const off_t len_,
const int advice_)
{ {
return (errno=EOPNOTSUPP,-1); return (errno=EOPNOTSUPP,-1);
} }

8
src/fs_base_fallocate.cpp → src/fs_fallocate.cpp

@ -17,11 +17,11 @@
#include <fcntl.h> #include <fcntl.h>
#ifdef __linux__ #ifdef __linux__
# include "fs_base_fallocate_linux.icpp"
# include "fs_fallocate_linux.icpp"
#elif _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L #elif _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L
# include "fs_base_fallocate_posix.icpp"
# include "fs_fallocate_posix.icpp"
#elif __APPLE__ #elif __APPLE__
# include "fs_base_fallocate_osx.icpp"
# include "fs_fallocate_osx.icpp"
#else #else
# include "fs_base_fallocate_unsupported.icpp"
# include "fs_fallocate_unsupported.icpp"
#endif #endif

9
src/fs_base_fallocate_unsupported.icpp → src/fs_fallocate.hpp

@ -14,7 +14,9 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "errno.hpp"
#pragma once
#include <fcntl.h>
namespace fs namespace fs
{ {
@ -22,8 +24,5 @@ namespace fs
fallocate(const int fd, fallocate(const int fd,
const int mode, const int mode,
const off_t offset, const off_t offset,
const off_t len)
{
return (errno=EOPNOTSUPP,-1);
}
const off_t len);
} }

7
src/fs_base_fallocate.hpp → src/fs_fallocate_linux.icpp

@ -14,8 +14,6 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#pragma once
#include <fcntl.h> #include <fcntl.h>
namespace fs namespace fs
@ -24,5 +22,8 @@ namespace fs
fallocate(const int fd_, fallocate(const int fd_,
const int mode_, const int mode_,
const off_t offset_, const off_t offset_,
const off_t len_);
const off_t len_)
{
return ::fallocate(fd_,mode_,offset_,len_);
}
} }

47
src/fs_base_fallocate_osx.icpp → src/fs_fallocate_osx.icpp

@ -19,39 +19,42 @@
#include "errno.hpp" #include "errno.hpp"
static
int
_fallocate_core(const int fd,
const off_t offset,
const off_t len)
namespace l
{ {
int rv;
fstore_t store = {F_ALLOCATECONTIG,F_PEOFPOSMODE,offset,len,0};
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);
}
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;
if(rv == -1)
return rv;
return ::ftruncate(fd,(offset+len));
return ::ftruncate(fd_,(offset_+len_));
}
} }
namespace fs namespace fs
{ {
int int
fallocate(const int fd,
const int mode,
const off_t offset,
const off_t len)
fallocate(const int fd_,
const int mode_,
const off_t offset_,
const off_t len_)
{ {
if(mode)
if(mode_)
return (errno=EOPNOTSUPP,-1); return (errno=EOPNOTSUPP,-1);
return ::_fallocate_core(fd,offset,len);
return l::fallocate_core(fd_,offset_,len_);
} }
} }

17
src/fs_base_fallocate_linux.icpp → src/fs_fallocate_posix.icpp

@ -14,18 +14,21 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <fcntl.h>
#include "errno.hpp" #include "errno.hpp"
#include <fcntl.h>
namespace fs namespace fs
{ {
int int
fallocate(const int fd,
const int mode,
const off_t offset,
const off_t len)
fallocate(const int fd_,
const int mode_,
const off_t offset_,
const off_t len_)
{ {
return ::fallocate(fd,mode,offset,len);
if(mode_)
return (errno=EOPNOTSUPP,-1);
return ::posix_fallocate(fd_,offset_,len_);
} }
} }

29
src/fs_fallocate_unsupported.icpp

@ -0,0 +1,29 @@
/*
Copyright (c) 2016, 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 "errno.hpp"
namespace fs
{
int
fallocate(const int fd_,
const int mode_,
const off_t offset_,
const off_t len_)
{
return (errno=EOPNOTSUPP,-1);
}
}

2
src/fs_base_fchmod.hpp → src/fs_fchmod.hpp

@ -18,7 +18,7 @@
#pragma once #pragma once
#include "fs_base_stat.hpp"
#include "fs_fstat.hpp"
#include <sys/stat.h> #include <sys/stat.h>

49
src/fs_fchmodat.hpp

@ -0,0 +1,49 @@
/*
ISC License
Copyright (c) 2020, 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 <string>
#include <fcntl.h>
#include <sys/stat.h>
namespace fs
{
static
inline
int
fchmodat(const int dirfd_,
const char *pathname_,
const mode_t mode_,
const int flags_)
{
return ::fchmodat(dirfd_,pathname_,mode_,flags_);
}
static
inline
int
fchmodat(const int dirfd_,
const std::string &pathname_,
const mode_t mode_,
const int flags_)
{
return fs::fchmodat(dirfd_,pathname_.c_str(),mode_,flags_);
}
}

3
src/fs_base_fchown.hpp → src/fs_fchown.hpp

@ -18,7 +18,8 @@
#pragma once #pragma once
#include "fs_base_stat.hpp"
#include "errno.hpp"
#include "fs_fstat.hpp"
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>

8
src/fs_base_fsync.hpp → src/fs_fdatasync.hpp

@ -28,14 +28,6 @@
namespace fs namespace fs
{ {
static
inline
int
fsync(const int fd_)
{
return ::fsync(fd_);
}
static static
inline inline
int int

61
src/fs_fgetxattr.hpp

@ -0,0 +1,61 @@
/*
ISC License
Copyright (c) 2020, 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 "xattr.hpp"
#include <string>
#include <sys/types.h>
namespace fs
{
static
inline
int
fgetxattr(const int fd_,
const char *attrname_,
void *value_,
const size_t size_)
{
#ifdef USE_XATTR
return ::fgetxattr(fd_,
attrname_,
value_,
size_);
#else
return (errno=ENOTSUP,-1);
#endif
}
static
inline
int
fgetxattr(const int fd_,
const std::string &attrname_,
void *value_,
const size_t size_)
{
return fs::fgetxattr(fd_,
attrname_.c_str(),
value_,
size_);
}
}

6
src/fs_ficlone.cpp

@ -17,7 +17,9 @@
*/ */
#ifdef __linux__ #ifdef __linux__
# include "fs_ficlone_linux.icpp"
#warning "using fs_ficlone_linux.icpp"
#include "fs_ficlone_linux.icpp"
#else #else
# include "fs_ficlone_unsupported.icpp"
#warning "using fs_ficlone_unsupported.icpp"
#include "fs_ficlone_unsupported.icpp"
#endif #endif

4
src/fs_ficlone.hpp

@ -21,6 +21,6 @@
namespace fs namespace fs
{ {
int int
ficlone(const int src_fd_,
const int dst_fd_);
ficlone(const int src_fd,
const int dst_fd);
} }

2
src/fs_ficlone_linux.icpp

@ -17,7 +17,7 @@
*/ */
#include "errno.hpp" #include "errno.hpp"
#include "fs_base_ioctl.hpp"
#include "fs_ioctl.hpp"
#include <linux/fs.h> #include <linux/fs.h>

2
src/fs_file_size.cpp

@ -16,7 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "fs_base_stat.hpp"
#include "fs_fstat.hpp"
#include <stdint.h> #include <stdint.h>

44
src/fs_findallfiles.cpp

@ -0,0 +1,44 @@
/*
ISC License
Copyright (c) 2020, 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_exists.hpp"
#include "fs_path.hpp"
#include <string>
#include <vector>
namespace fs
{
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);
}
}
}

30
src/fs_findallfiles.hpp

@ -0,0 +1,30 @@
/*
ISC License
Copyright (c) 2020, 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 <string>
#include <vector>
namespace fs
{
void
findallfiles(const std::vector<std::string> &basepaths,
const char *fusepath,
std::vector<std::string> *paths);
}

3
src/fs_findonfs.cpp

@ -18,7 +18,8 @@
#include "branch.hpp" #include "branch.hpp"
#include "errno.hpp" #include "errno.hpp"
#include "fs_base_stat.hpp"
#include "fs_fstat.hpp"
#include "fs_lstat.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include <string> #include <string>

41
src/fs_flistxattr.hpp

@ -0,0 +1,41 @@
/*
ISC License
Copyright (c) 2016, 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 "xattr.hpp"
#include <sys/types.h>
namespace fs
{
static
inline
int
flistxattr(const int fd_,
char *list_,
const size_t size_)
{
#ifdef USE_XATTR
return ::flistxattr(fd_,list_,size_);
#else
return (errno=ENOTSUP,-1);
#endif
}
}

0
src/fs_base_flock.hpp → src/fs_flock.hpp

61
src/fs_fsetxattr.hpp

@ -0,0 +1,61 @@
/*
ISC License
Copyright (c) 2020, 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 "xattr.hpp"
#include <string>
#include <sys/types.h>
namespace fs
{
static
inline
int
fsetxattr(const int fd_,
const char *name_,
const void *value_,
const size_t size_,
const int flags_)
{
#ifdef USE_XATTR
return ::fsetxattr(fd_,name_,value_,size_,flags_);
#else
return (errno=ENOTSUP,-1);
#endif
}
static
inline
int
fsetxattr(const int fd_,
const std::string &name_,
const void *value_,
const size_t size_,
const int flags_)
{
return fs::fsetxattr(fd_,
name_.c_str(),
value_,
size_,
flags_);
}
}

36
src/fs_fstat.hpp

@ -0,0 +1,36 @@
/*
ISC License
Copyright (c) 2020, 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 <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
namespace fs
{
static
inline
int
fstat(const int fd_,
struct stat *st_)
{
return ::fstat(fd_,st_);
}
}

28
src/fs_base_fstatat.hpp → src/fs_fstatat.hpp

@ -28,27 +28,27 @@ namespace fs
static static
inline inline
int int
fstatat(const int dirfd,
const char *pathname,
struct stat *statbuf,
const int flags)
fstatat(const int dirfd_,
const char *pathname_,
struct stat *statbuf_,
const int flags_)
{ {
return ::fstatat(dirfd,
pathname,
statbuf,
flags);
return ::fstatat(dirfd_,
pathname_,
statbuf_,
flags_);
} }
static static
inline inline
int int
fstatat_nofollow(const int dirfd,
const char *pathname,
struct stat *statbuf)
fstatat_nofollow(const int dirfd_,
const char *pathname_,
struct stat *statbuf_)
{ {
return fs::fstatat(dirfd,
pathname,
statbuf,
return fs::fstatat(dirfd_,
pathname_,
statbuf_,
AT_SYMLINK_NOFOLLOW); AT_SYMLINK_NOFOLLOW);
} }
} }

32
src/fs_fsync.hpp

@ -0,0 +1,32 @@
/*
ISC License
Copyright (c) 2016, 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 <unistd.h>
namespace fs
{
static
inline
int
fsync(const int fd_)
{
return ::fsync(fd_);
}
}

0
src/fs_base_ftruncate.hpp → src/fs_ftruncate.hpp

51
src/fs_futimens.hpp

@ -0,0 +1,51 @@
/*
ISC License
Copyright (c) 2020, 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_stat_utils.hpp"
#include <sys/stat.h>
#ifdef __linux__
#warning "using fs_futimens_linux.hpp"
#include "fs_futimens_linux.hpp"
#elif __FreeBSD__ >= 11
#warning "using fs_futimens_freebsd_11.hpp"
#include "fs_futimens_freebsd_11.hpp"
#else
#warning "using fs_futimens_generic.hpp"
#include "fs_futimens_generic.hpp"
#endif
namespace fs
{
static
inline
int
futimens(const int fd_,
const struct stat &st_)
{
struct timespec ts[2];
ts[0] = *fs::stat_atime(&st_);
ts[1] = *fs::stat_mtime(&st_);
return fs::futimens(fd_,ts);
}
}

33
src/fs_futimens_freebsd_11.hpp

@ -0,0 +1,33 @@
/*
ISC License
Copyright (c) 2020, 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 <sys/stat.h>
namespace fs
{
static
inline
int
futimens(const int fd_,
const struct timespec ts_[2])
{
return ::futimens(fd_,ts_);
}
}

283
src/fs_futimens_generic.hpp

@ -0,0 +1,283 @@
/*
ISC License
Copyright (c) 2020, 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_futimesat.hpp"
#include "fs_stat_utils.hpp"
#include <string>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#ifndef UTIME_NOW
# define UTIME_NOW ((1l << 30) - 1l)
#endif
#ifndef UTIME_OMIT
# define UTIME_OMIT ((1l << 30) - 2l)
#endif
namespace l
{
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] == '/')));
}
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
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
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_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;
if(!l::any_timespec_is_utime_omit(ts_))
return 0;
rv = fs::fstatat(dirfd_,path_,&st,flags_);
if(rv == -1)
return -1;
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);
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;
if(!l::any_timespec_is_utime_omit(ts_))
return 0;
rv = fs::fstat(fd_,&st);
if(rv == -1)
return -1;
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);
return 0;
}
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;
rv = time::gettimeofday(&now,NULL);
if(rv == -1)
return -1;
if(ts_[0].tv_nsec == UTIME_NOW)
tv_[0] = now;
if(ts_[1].tv_nsec == UTIME_NOW)
tv_[1] = now;
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;
if(l::should_be_set_to_now(ts_))
return (tvp=NULL,0);
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 = l::set_utime_now_to_now(ts_,tv_);
if(rv == -1)
return -1;
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;
if(l::should_be_set_to_now(ts_))
return (*tvp=NULL,0);
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 = l::set_utime_now_to_now(ts_,tv_);
if(rv == -1)
return -1;
return (*tvp=tv,0);
}
}
namespace fs
{
static
inline
int
futimens(const int fd_,
const struct timespec ts_[2])
{
int rv;
struct timeval tv[2];
struct timeval *tvp;
if(l::timespec_invalid(ts_))
return (errno=EINVAL,-1);
if(l::should_ignore(ts_))
return 0;
rv = l::convert_timespec_to_timeval(fd_,ts_,tv,&tvp);
if(rv == -1)
return -1;
return ::futimes(fd_,tvp);
}
}

33
src/fs_futimens_linux.hpp

@ -0,0 +1,33 @@
/*
ISC License
Copyright (c) 2020, 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 <sys/stat.h>
namespace fs
{
static
inline
int
futimens(const int fd_,
const struct timespec ts_[2])
{
return ::futimens(fd_,ts_);
}
}

6
src/fs_base_futimesat.cpp → src/fs_futimesat.cpp

@ -17,7 +17,9 @@
*/ */
#if __APPLE__ #if __APPLE__
# include "fs_base_futimesat_osx.icpp"
#warning "using fs_futimesat_osx.icpp"
#include "fs_futimesat_osx.icpp"
#else #else
# include "fs_base_futimesat_generic.icpp"
#warning "using fs_futimesat_generic.icpp"
#include "fs_futimesat_generic.icpp"
#endif #endif

8
src/fs_base_futimesat_generic.icpp → src/fs_futimesat.hpp

@ -16,7 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <fcntl.h>
#pragma once
#include <sys/time.h> #include <sys/time.h>
namespace fs namespace fs
@ -24,8 +25,5 @@ namespace fs
int int
futimesat(const int dirfd, futimesat(const int dirfd,
const char *pathname, const char *pathname,
const struct timeval times[2])
{
return ::futimesat(dirfd,pathname,times);
}
const struct timeval times[2]);
} }

8
src/fs_base_futimesat.hpp → src/fs_futimesat_generic.icpp

@ -16,8 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#pragma once
#include <fcntl.h>
#include <sys/time.h> #include <sys/time.h>
namespace fs namespace fs
@ -25,5 +24,8 @@ namespace fs
int int
futimesat(const int dirfd_, futimesat(const int dirfd_,
const char *pathname_, const char *pathname_,
const struct timeval times_[2]);
const struct timeval times_[2])
{
return ::futimesat(dirfd_,pathname_,times_);
}
} }

67
src/fs_base_futimesat_osx.icpp → src/fs_futimesat_osx.icpp

@ -26,59 +26,62 @@
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
static
int
getpath(const int dirfd,
const char *path,
char *fullpath)
namespace l
{ {
int rv;
struct stat st;
static
int
getpath(const int dirfd_,
const char *path_,
char *fullpath_)
{
int rv;
struct stat st;
rv = ::fstat(dirfd,&st);
if(rv == -1)
return -1;
rv = ::fstat(dirfd_,&st);
if(rv == -1)
return -1;
if(!S_ISDIR(st.st_mode))
return (errno=ENOTDIR,-1);
if(!S_ISDIR(st.st_mode))
return (errno=ENOTDIR,-1);
rv = ::fcntl(dirfd,F_GETPATH,fullpath);
if(rv == -1)
return -1;
rv = ::fcntl(dirfd_,F_GETPATH,fullpath);
if(rv == -1)
return -1;
rv = ::strlcat(fullpath,"/",MAXPATHLEN);
if(rv > MAXPATHLEN)
return (errno=ENAMETOOLONG,-1);
rv = ::strlcat(fullpath_,"/",MAXPATHLEN);
if(rv > MAXPATHLEN)
return (errno=ENAMETOOLONG,-1);
rv = ::strlcat(fullpath,path,MAXPATHLEN);
if(rv > MAXPATHLEN)
return (errno=ENAMETOOLONG,-1);
rv = ::strlcat(fullpath_,path_,MAXPATHLEN);
if(rv > MAXPATHLEN)
return (errno=ENAMETOOLONG,-1);
return 0;
return 0;
}
} }
namespace fs namespace fs
{ {
int int
futimesat(const int dirfd,
const char *pathname,
const struct timeval times[2])
futimesat(const int dirfd_,
const char *pathname_,
const struct timeval times_[2])
{ {
int rv; int rv;
char fullpath[MAXPATHLEN]; char fullpath[MAXPATHLEN];
if((dirfd == AT_FDCWD) ||
((pathname != NULL) &&
(pathname[0] == '/')))
return ::utimes(pathname,times);
if((dirfd_ == AT_FDCWD) ||
((pathname_ != NULL) &&
(pathname_[0] == '/')))
return ::utimes(pathname_,times_);
if(dirfd < 0)
if(dirfd_ < 0)
return (errno=EBADF,-1); return (errno=EBADF,-1);
rv = getpath(dirfd,pathname,fullpath);
rv = l::getpath(dirfd_,pathname_,fullpath);
if(rv == -1) if(rv == -1)
return -1; return -1;
return ::utimes(fullpath,times);
return ::utimes(fullpath,times_);
} }
} }

6
src/fs_base_getdents.cpp → src/fs_getdents64.cpp

@ -26,9 +26,9 @@
namespace fs namespace fs
{ {
int int
getdents(unsigned int fd_,
void *dirp_,
unsigned int count_)
getdents_64(unsigned int fd_,
void *dirp_,
unsigned int count_)
{ {
#if defined SYS_getdents64 #if defined SYS_getdents64
return ::syscall(SYS_getdents64,fd_,dirp_,count_); return ::syscall(SYS_getdents64,fd_,dirp_,count_);

27
src/fs_getdents64.hpp

@ -0,0 +1,27 @@
/*
ISC License
Copyright (c) 2020, 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
namespace fs
{
int
getdents_64(unsigned int fd,
void *dirp,
unsigned int count);
}

28
src/fs_getfl.cpp

@ -0,0 +1,28 @@
/*
ISC License
Copyright (c) 2020, 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 <fcntl.h>
namespace fs
{
int
getfl(const int fd_)
{
return ::fcntl(fd_,F_GETFL,0);
}
}

24
src/fs_getfl.hpp

@ -0,0 +1,24 @@
/*
ISC License
Copyright (c) 2020, 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
namespace fs
{
int getfl(const int fd);
}

4
src/fs_glob.cpp

@ -28,7 +28,7 @@ namespace fs
{ {
void void
glob(const string &pattern_, glob(const string &pattern_,
vector<string> &strs_)
vector<string> *strs_)
{ {
int flags; int flags;
glob_t gbuf = {0}; glob_t gbuf = {0};
@ -37,7 +37,7 @@ namespace fs
::glob(pattern_.c_str(),flags,NULL,&gbuf); ::glob(pattern_.c_str(),flags,NULL,&gbuf);
for(size_t i = 0; i < gbuf.gl_pathc; i++) for(size_t i = 0; i < gbuf.gl_pathc; i++)
strs_.push_back(gbuf.gl_pathv[i]);
strs_->push_back(gbuf.gl_pathv[i]);
::globfree(&gbuf); ::globfree(&gbuf);
} }

4
src/fs_glob.hpp

@ -22,6 +22,6 @@
namespace fs namespace fs
{ {
void void
glob(const std::string &pattern_,
std::vector<std::string> &strs_);
glob(const std::string &pattern,
std::vector<std::string> *strs);
} }

2
src/fs_has_space.cpp

@ -16,7 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "fs_base_statvfs.hpp"
#include "fs_statvfs.hpp"
#include "statvfs_util.hpp" #include "statvfs_util.hpp"
#include <string> #include <string>

8
src/fs_info.cpp

@ -16,10 +16,10 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "fs_base_stat.hpp"
#include "fs_base_statvfs.hpp"
#include "fs_info_t.hpp" #include "fs_info_t.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "fs_stat.hpp"
#include "fs_statvfs.hpp"
#include "fs_statvfs_cache.hpp" #include "fs_statvfs_cache.hpp"
#include "statvfs_util.hpp" #include "statvfs_util.hpp"
@ -32,13 +32,13 @@ using std::string;
namespace fs namespace fs
{ {
int int
info(const string *path_,
info(const string &path_,
fs::info_t *info_) fs::info_t *info_)
{ {
int rv; int rv;
struct statvfs st; struct statvfs st;
rv = fs::statvfs_cache(path_->c_str(),&st);
rv = fs::statvfs_cache(path_.c_str(),&st);
if(rv == 0) if(rv == 0)
{ {
info_->readonly = StatVFS::readonly(st); info_->readonly = StatVFS::readonly(st);

4
src/fs_info.hpp

@ -25,6 +25,6 @@
namespace fs namespace fs
{ {
int int
info(const std::string *path_,
fs::info_t *info_);
info(const std::string &path,
fs::info_t *info);
} }

0
src/fs_base_ioctl.hpp → src/fs_ioctl.hpp

30
src/fs_base_chmod.hpp → src/fs_lchmod.hpp

@ -1,7 +1,7 @@
/* /*
ISC License ISC License
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -18,9 +18,10 @@
#pragma once #pragma once
#include "fs_base_stat.hpp"
#include "fs_fchmodat.hpp"
#include "fs_lstat.hpp"
#include <sys/stat.h>
#include <string>
#define MODE_BITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) #define MODE_BITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
@ -29,28 +30,37 @@ namespace fs
static static
inline inline
int int
chmod(const std::string &path_,
const mode_t mode_)
lchmod(const char *pathname_,
const mode_t mode_)
{ {
return ::chmod(path_.c_str(),mode_);
return fs::fchmodat(AT_FDCWD,pathname_,mode_,AT_SYMLINK_NOFOLLOW);
} }
static static
inline inline
int int
chmod_check_on_error(const std::string &path_,
const mode_t mode_)
lchmod(const std::string &pathname_,
const mode_t mode_)
{
return fs::lchmod(pathname_.c_str(),mode_);
}
static
inline
int
lchmod_check_on_error(const std::string &path_,
const mode_t mode_)
{ {
int rv; int rv;
rv = fs::chmod(path_,mode_);
rv = fs::lchmod(path_,mode_);
if(rv == -1) if(rv == -1)
{ {
int error; int error;
struct stat st; struct stat st;
error = errno; error = errno;
rv = fs::stat(path_,&st);
rv = fs::lstat(path_,&st);
if(rv == -1) if(rv == -1)
return -1; return -1;

34
src/fs_base_chown.hpp → src/fs_lchown.hpp

@ -1,7 +1,7 @@
/* /*
ISC License ISC License
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -18,12 +18,8 @@
#pragma once #pragma once
#include "fs_base_stat.hpp"
#include "fs_lstat.hpp"
#include <string>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h> #include <unistd.h>
namespace fs namespace fs
@ -31,39 +27,39 @@ namespace fs
static static
inline inline
int int
chown(const std::string &path_,
const uid_t uid_,
const gid_t gid_)
lchown(const char *pathname_,
const uid_t uid_,
const gid_t gid_)
{ {
return ::chown(path_.c_str(),uid_,gid_);
return ::lchown(pathname_,uid_,gid_);
} }
static static
inline inline
int int
chown(const std::string &path_,
const struct stat &st_)
lchown(const std::string &pathname_,
const uid_t uid_,
const gid_t gid_)
{ {
return fs::chown(path_,st_.st_uid,st_.st_gid);
return fs::lchown(pathname_.c_str(),uid_,gid_);
} }
static static
inline inline
int int
lchown(const std::string &path_,
const uid_t uid_,
const gid_t gid_)
lchown(const char *pathname_,
const struct stat &st_)
{ {
return ::lchown(path_.c_str(),uid_,gid_);
return fs::lchown(pathname_,st_.st_uid,st_.st_gid);
} }
static static
inline inline
int int
lchown(const std::string &path_,
lchown(const std::string &pathname_,
const struct stat &st_) const struct stat &st_)
{ {
return fs::lchown(path_,st_.st_uid,st_.st_gid);
return fs::lchown(pathname_.c_str(),st_);
} }
static static

38
src/fs_base_getxattr.hpp → src/fs_lgetxattr.hpp

@ -1,7 +1,7 @@
/* /*
ISC License ISC License
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -36,7 +36,10 @@ namespace fs
const size_t size_) const size_t size_)
{ {
#ifdef USE_XATTR #ifdef USE_XATTR
return ::lgetxattr(path_,attrname_,value_,size_);
return ::lgetxattr(path_,
attrname_,
value_,
size_);
#else #else
return (errno=ENOTSUP,-1); return (errno=ENOTSUP,-1);
#endif #endif
@ -50,7 +53,10 @@ namespace fs
void *value_, void *value_,
const size_t size_) const size_t size_)
{ {
return fs::lgetxattr(path_.c_str(),attrname_,value_,size_);
return fs::lgetxattr(path_.c_str(),
attrname_,
value_,
size_);
} }
static static
@ -66,30 +72,4 @@ namespace fs
value_, value_,
size_); size_);
} }
static
inline
int
fgetxattr(const int fd_,
const char *attrname_,
void *value_,
const size_t size_)
{
#ifdef USE_XATTR
return ::fgetxattr(fd_,attrname_,value_,size_);
#else
return (errno=ENOTSUP,-1);
#endif
}
static
inline
int
fgetxattr(const int fd_,
const std::string &attrname_,
void *value_,
const size_t size_)
{
return fs::fgetxattr(fd_,attrname_.c_str(),value_,size_);
}
} }

0
src/fs_base_link.hpp → src/fs_link.hpp

14
src/fs_base_listxattr.hpp → src/fs_llistxattr.hpp

@ -50,18 +50,4 @@ namespace fs
{ {
return fs::llistxattr(path_.c_str(),list_,size_); return fs::llistxattr(path_.c_str(),list_,size_);
} }
static
inline
int
flistxattr(const int fd_,
char *list_,
const size_t size_)
{
#ifdef USE_XATTR
return ::flistxattr(fd_,list_,size_);
#else
return (errno=ENOTSUP,-1);
#endif
}
} }

0
src/fs_base_removexattr.hpp → src/fs_lremovexattr.hpp

0
src/fs_base_lseek.hpp → src/fs_lseek.hpp

24
src/fs_base_setxattr.hpp → src/fs_lsetxattr.hpp

@ -1,7 +1,7 @@
/* /*
ISC License ISC License
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -37,7 +37,11 @@ namespace fs
const int flags_) const int flags_)
{ {
#ifdef USE_XATTR #ifdef USE_XATTR
return ::lsetxattr(path_,name_,value_,size_,flags_);
return ::lsetxattr(path_,
name_,
value_,
size_,
flags_);
#else #else
return (errno=ENOTSUP,-1); return (errno=ENOTSUP,-1);
#endif #endif
@ -58,20 +62,4 @@ namespace fs
size_, size_,
flags_); flags_);
} }
static
inline
int
fsetxattr(const int fd_,
const char *name_,
const void *value_,
const size_t size_,
const int flags_)
{
#ifdef USE_XATTR
return ::fsetxattr(fd_,name_,value_,size_,flags_);
#else
return (errno=ENOTSUP,-1);
#endif
}
} }

46
src/fs_lstat.hpp

@ -0,0 +1,46 @@
/*
ISC License
Copyright (c) 2016, 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 <string>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
namespace fs
{
static
inline
int
lstat(const char *path_,
struct stat *st_)
{
return ::lstat(path_,st_);
}
static
inline
int
lstat(const std::string &path_,
struct stat *st_)
{
return fs::lstat(path_.c_str(),st_);
}
}

48
src/fs_lutimens.hpp

@ -0,0 +1,48 @@
/*
ISC License
Copyright (c) 2020, 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_utimensat.hpp"
#include "fs_stat_utils.hpp"
namespace fs
{
static
inline
int
lutimens(const std::string &path_,
const struct timespec ts_[2])
{
return fs::utimensat(AT_FDCWD,path_,ts_,AT_SYMLINK_NOFOLLOW);
}
static
inline
int
lutimens(const std::string &path_,
const struct stat &st_)
{
struct timespec ts[2];
ts[0] = *fs::stat_atime(&st_);
ts[1] = *fs::stat_mtime(&st_);
return fs::lutimens(path_,ts);
}
}

0
src/fs_base_mkdir.hpp → src/fs_mkdir.hpp

0
src/fs_base_mknod.hpp → src/fs_mknod.hpp

8
src/fs_mktemp.cpp

@ -17,7 +17,7 @@
*/ */
#include "errno.hpp" #include "errno.hpp"
#include "fs_base_open.hpp"
#include "fs_open.hpp"
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
@ -48,7 +48,7 @@ generate_tmp_path(const string &base_)
namespace fs namespace fs
{ {
int int
mktemp(string &base_,
mktemp(string *base_,
const int flags_) const int flags_)
{ {
int fd; int fd;
@ -61,13 +61,13 @@ namespace fs
flags = (flags_ | O_EXCL | O_CREAT); flags = (flags_ | O_EXCL | O_CREAT);
while(count-- > 0) while(count-- > 0)
{ {
tmppath = generate_tmp_path(base_);
tmppath = generate_tmp_path(*base_);
fd = fs::open(tmppath,flags,S_IWUSR); fd = fs::open(tmppath,flags,S_IWUSR);
if((fd == -1) && (errno == EEXIST)) if((fd == -1) && (errno == EEXIST))
continue; continue;
else if(fd != -1) else if(fd != -1)
base_ = tmppath;
*base_ = tmppath;
return fd; return fd;
} }

4
src/fs_mktemp.hpp

@ -23,6 +23,6 @@
namespace fs namespace fs
{ {
int int
mktemp(std::string &base_,
const int flags_);
mktemp(std::string *base,
const int flags);
} }

14
src/fs_movefile.cpp

@ -15,19 +15,19 @@
*/ */
#include "errno.hpp" #include "errno.hpp"
#include "fs.hpp"
#include "fs_base_close.hpp"
#include "fs_base_open.hpp"
#include "fs_base_rename.hpp"
#include "fs_base_stat.hpp"
#include "fs_base_unlink.hpp"
#include "fs_clonefile.hpp" #include "fs_clonefile.hpp"
#include "fs_clonepath.hpp" #include "fs_clonepath.hpp"
#include "fs_close.hpp"
#include "fs_file_size.hpp" #include "fs_file_size.hpp"
#include "fs_findonfs.hpp" #include "fs_findonfs.hpp"
#include "fs_getfl.hpp"
#include "fs_has_space.hpp" #include "fs_has_space.hpp"
#include "fs_mktemp.hpp" #include "fs_mktemp.hpp"
#include "fs_open.hpp"
#include "fs_path.hpp" #include "fs_path.hpp"
#include "fs_rename.hpp"
#include "fs_stat.hpp"
#include "fs_unlink.hpp"
#include "policy.hpp" #include "policy.hpp"
#include "ugid.hpp" #include "ugid.hpp"
@ -97,7 +97,7 @@ namespace l
fs::path::append(fdout_path[0],fusepath_); fs::path::append(fdout_path[0],fusepath_);
fdout_temp = fdout_path[0]; fdout_temp = fdout_path[0];
fdout = fs::mktemp(fdout_temp,fdin_flags);
fdout = fs::mktemp(&fdout_temp,fdin_flags);
if(fdout == -1) if(fdout == -1)
return -1; return -1;

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

Loading…
Cancel
Save