mirror of https://github.com/trapexit/mergerfs.git
Browse Source
Merge pull request #144 from trapexit/enospc
Merge pull request #144 from trapexit/enospc
move on enospc when writing feature. closes #141pull/145/head
Antonio SJ Musumeci
9 years ago
66 changed files with 1834 additions and 662 deletions
-
16Makefile
-
20README.md
-
4src/access.cpp
-
4src/chmod.cpp
-
4src/chown.cpp
-
69src/clone.cpp
-
2src/clone.hpp
-
1src/config.cpp
-
1src/config.hpp
-
14src/create.cpp
-
2src/create.hpp
-
6src/fallocate.cpp
-
6src/fgetattr.cpp
-
36src/fileinfo.hpp
-
6src/flush.cpp
-
486src/fs.cpp
-
91src/fs.hpp
-
135src/fs_attr.cpp
-
43src/fs_attr.hpp
-
231src/fs_clonefile.cpp
-
33src/fs_clonefile.hpp
-
117src/fs_clonepath.cpp
-
32src/fs_clonepath.hpp
-
117src/fs_movefile.cpp
-
37src/fs_movefile.hpp
-
118src/fs_path.cpp
-
76src/fs_path.hpp
-
399src/fs_xattr.cpp
-
78src/fs_xattr.hpp
-
6src/fsync.cpp
-
6src/ftruncate.cpp
-
4src/getattr.cpp
-
16src/getxattr.cpp
-
7src/ioctl.cpp
-
5src/link.cpp
-
9src/listxattr.cpp
-
8src/mergerfs.cpp
-
5src/mkdir.cpp
-
5src/mknod.cpp
-
13src/open.cpp
-
2src/open.hpp
-
17src/option_parser.cpp
-
1src/policy.hpp
-
3src/policy_all.cpp
-
1src/policy_epmfs.cpp
-
2src/policy_ff.cpp
-
3src/policy_ffwp.cpp
-
3src/policy_fwfs.cpp
-
3src/policy_lfs.cpp
-
3src/policy_mfs.cpp
-
3src/policy_newest.cpp
-
6src/read.cpp
-
6src/read_buf.cpp
-
8src/readdir.cpp
-
4src/readlink.cpp
-
12src/release.cpp
-
4src/removexattr.cpp
-
4src/rename.cpp
-
4src/rmdir.cpp
-
32src/setxattr.cpp
-
4src/symlink.cpp
-
4src/truncate.cpp
-
4src/unlink.cpp
-
4src/utimens.cpp
-
33src/write.cpp
-
44src/write_buf.cpp
@ -0,0 +1,69 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include <errno.h>
|
||||
|
#include <unistd.h>
|
||||
|
#include <string.h>
|
||||
|
|
||||
|
#include <iostream>
|
||||
|
|
||||
|
#include "fs.hpp"
|
||||
|
#include "fs_clonefile.hpp"
|
||||
|
#include "fs_clonepath.hpp"
|
||||
|
|
||||
|
namespace clonetool |
||||
|
{ |
||||
|
static |
||||
|
void |
||||
|
print_usage_and__exit(void) |
||||
|
{ |
||||
|
std::cerr << "usage: clone " |
||||
|
<< "[path <sourcedir> <destdir> <relativepath>]" |
||||
|
<< " | " |
||||
|
<< "[file <source> <dest>]" |
||||
|
<< std::endl; |
||||
|
_exit(1); |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
main(const int argc, |
||||
|
char * const argv[]) |
||||
|
{ |
||||
|
int rv = 0; |
||||
|
|
||||
|
if(argc == 4 && !strcmp(argv[1],"file")) |
||||
|
rv = fs::clonefile(argv[2],argv[3]); |
||||
|
else if(argc == 5 && !strcmp(argv[1],"path")) |
||||
|
rv = fs::clonepath(argv[2],argv[3],argv[4]); |
||||
|
else |
||||
|
print_usage_and__exit(); |
||||
|
|
||||
|
if(rv == -1) |
||||
|
std::cerr << "error: " |
||||
|
<< strerror(errno) |
||||
|
<< std::endl; |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
} |
@ -0,0 +1,135 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2015 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include <errno.h>
|
||||
|
#include <fcntl.h>
|
||||
|
#include <linux/fs.h>
|
||||
|
#include <sys/ioctl.h>
|
||||
|
#include <sys/stat.h>
|
||||
|
#include <sys/types.h>
|
||||
|
#include <unistd.h>
|
||||
|
|
||||
|
#include <string>
|
||||
|
|
||||
|
using std::string; |
||||
|
|
||||
|
namespace fs |
||||
|
{ |
||||
|
namespace attr |
||||
|
{ |
||||
|
static |
||||
|
int |
||||
|
get_fs_ioc_flags(const int fd, |
||||
|
int &flags) |
||||
|
{ |
||||
|
return ::ioctl(fd,FS_IOC_GETFLAGS,&flags); |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
int |
||||
|
get_fs_ioc_flags(const string &file, |
||||
|
int &flags) |
||||
|
{ |
||||
|
int fd; |
||||
|
int rv; |
||||
|
const int openflags = O_RDONLY|O_NONBLOCK; |
||||
|
|
||||
|
fd = ::open(file.c_str(),openflags); |
||||
|
if(fd == -1) |
||||
|
return -1; |
||||
|
|
||||
|
rv = get_fs_ioc_flags(fd,flags); |
||||
|
if(rv == -1) |
||||
|
{ |
||||
|
int error = errno; |
||||
|
::close(fd); |
||||
|
errno = error; |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
return ::close(fd); |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
int |
||||
|
set_fs_ioc_flags(const int fd, |
||||
|
const int flags) |
||||
|
{ |
||||
|
return ::ioctl(fd,FS_IOC_SETFLAGS,&flags); |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
int |
||||
|
set_fs_ioc_flags(const string &file, |
||||
|
const int flags) |
||||
|
{ |
||||
|
int fd; |
||||
|
int rv; |
||||
|
const int openflags = O_RDONLY|O_NONBLOCK; |
||||
|
|
||||
|
fd = ::open(file.c_str(),openflags); |
||||
|
if(fd == -1) |
||||
|
return -1; |
||||
|
|
||||
|
rv = set_fs_ioc_flags(fd,flags); |
||||
|
if(rv == -1) |
||||
|
{ |
||||
|
int error = errno; |
||||
|
::close(fd); |
||||
|
errno = error; |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
return ::close(fd); |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
copy(const int fdin, |
||||
|
const int fdout) |
||||
|
{ |
||||
|
int rv; |
||||
|
int flags; |
||||
|
|
||||
|
rv = get_fs_ioc_flags(fdin,flags); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
return set_fs_ioc_flags(fdout,flags); |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
copy(const string &from, |
||||
|
const string &to) |
||||
|
{ |
||||
|
int rv; |
||||
|
int flags; |
||||
|
|
||||
|
rv = get_fs_ioc_flags(from,flags); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
return set_fs_ioc_flags(to,flags); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,43 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __FS_ATTR_HPP__
|
||||
|
#define __FS_ATTR_HPP__
|
||||
|
|
||||
|
#include <string>
|
||||
|
|
||||
|
namespace fs |
||||
|
{ |
||||
|
namespace attr |
||||
|
{ |
||||
|
using std::string; |
||||
|
|
||||
|
int copy(const int fdin, |
||||
|
const int fdout); |
||||
|
int copy(const string &from, |
||||
|
const string &to); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endif // __FS_ATTR_HPP__
|
@ -0,0 +1,231 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2015 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include <stdlib.h>
|
||||
|
#include <sys/types.h>
|
||||
|
#include <sys/stat.h>
|
||||
|
#include <unistd.h>
|
||||
|
#include <fcntl.h>
|
||||
|
#include <errno.h>
|
||||
|
#ifdef __linux__
|
||||
|
#include <sys/sendfile.h>
|
||||
|
#endif
|
||||
|
|
||||
|
#include <string>
|
||||
|
#include <vector>
|
||||
|
|
||||
|
#include "fs_attr.hpp"
|
||||
|
#include "fs_xattr.hpp"
|
||||
|
|
||||
|
using std::string; |
||||
|
using std::vector; |
||||
|
|
||||
|
namespace fs |
||||
|
{ |
||||
|
static |
||||
|
ssize_t |
||||
|
sendfile(const int fdin, |
||||
|
const int fdout, |
||||
|
const size_t count) |
||||
|
{ |
||||
|
#if defined __linux__
|
||||
|
off_t offset = 0; |
||||
|
return ::sendfile(fdout,fdin,&offset,count); |
||||
|
#else
|
||||
|
return (errno=EINVAL,-1); |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
int |
||||
|
writen(const int fd, |
||||
|
const char *buf, |
||||
|
const size_t count) |
||||
|
{ |
||||
|
size_t nleft; |
||||
|
ssize_t nwritten; |
||||
|
|
||||
|
nleft = count; |
||||
|
while(nleft > 0) |
||||
|
{ |
||||
|
nwritten = ::write(fd,buf,nleft); |
||||
|
if(nwritten == -1) |
||||
|
{ |
||||
|
if(errno == EINTR) |
||||
|
continue; |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
nleft -= nwritten; |
||||
|
buf += nwritten; |
||||
|
} |
||||
|
|
||||
|
return count; |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
int |
||||
|
copyfile_rw(const int fdin, |
||||
|
const int fdout, |
||||
|
const size_t count, |
||||
|
const size_t blocksize) |
||||
|
{ |
||||
|
ssize_t nr; |
||||
|
ssize_t nw; |
||||
|
ssize_t bufsize; |
||||
|
size_t totalwritten; |
||||
|
vector<char> buf; |
||||
|
|
||||
|
bufsize = (blocksize * 16); |
||||
|
buf.resize(bufsize); |
||||
|
|
||||
|
totalwritten = 0; |
||||
|
while(totalwritten < count) |
||||
|
{ |
||||
|
nr = ::read(fdin,&buf[0],bufsize); |
||||
|
if(nr == -1) |
||||
|
{ |
||||
|
if(errno == EINTR) |
||||
|
continue; |
||||
|
else |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
nw = writen(fdout,&buf[0],nr); |
||||
|
if(nw == -1) |
||||
|
return -1; |
||||
|
|
||||
|
totalwritten += nw; |
||||
|
} |
||||
|
|
||||
|
return count; |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
int |
||||
|
copydata(const int fdin, |
||||
|
const int fdout, |
||||
|
const size_t count, |
||||
|
const size_t blocksize) |
||||
|
{ |
||||
|
int rv; |
||||
|
|
||||
|
::posix_fadvise(fdin,0,count,POSIX_FADV_WILLNEED); |
||||
|
::posix_fadvise(fdin,0,count,POSIX_FADV_SEQUENTIAL); |
||||
|
|
||||
|
::posix_fallocate(fdout,0,count); |
||||
|
|
||||
|
rv = fs::sendfile(fdin,fdout,count); |
||||
|
if((rv == -1) && ((errno == EINVAL) || (errno == ENOSYS))) |
||||
|
return fs::copyfile_rw(fdin,fdout,count,blocksize); |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
bool |
||||
|
ignorable_error(const int err) |
||||
|
{ |
||||
|
switch(err) |
||||
|
{ |
||||
|
case ENOTTY: |
||||
|
case ENOTSUP: |
||||
|
#if ENOTSUP != EOPNOTSUPP
|
||||
|
case EOPNOTSUPP: |
||||
|
#endif
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
clonefile(const int fdin, |
||||
|
const int fdout) |
||||
|
{ |
||||
|
int rv; |
||||
|
struct stat stin; |
||||
|
|
||||
|
rv = ::fstat(fdin,&stin); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
rv = copydata(fdin,fdout,stin.st_size,stin.st_blksize); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
rv = fs::attr::copy(fdin,fdout); |
||||
|
if(rv == -1 && !ignorable_error(errno)) |
||||
|
return -1; |
||||
|
|
||||
|
rv = fs::xattr::copy(fdin,fdout); |
||||
|
if(rv == -1 && !ignorable_error(errno)) |
||||
|
return -1; |
||||
|
|
||||
|
rv = ::fchown(fdout,stin.st_uid,stin.st_gid); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
rv = ::fchmod(fdout,stin.st_mode); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
struct timespec times[2]; |
||||
|
times[0] = stin.st_atim; |
||||
|
times[1] = stin.st_mtim; |
||||
|
rv = ::futimens(fdout,times); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
clonefile(const string &in, |
||||
|
const string &out) |
||||
|
{ |
||||
|
int rv; |
||||
|
int fdin; |
||||
|
int fdout; |
||||
|
int error; |
||||
|
|
||||
|
fdin = ::open(in.c_str(),O_RDONLY|O_NOFOLLOW); |
||||
|
if(fdin == -1) |
||||
|
return -1; |
||||
|
|
||||
|
const int flags = O_CREAT|O_LARGEFILE|O_NOATIME|O_NOFOLLOW|O_TRUNC|O_WRONLY; |
||||
|
const int mode = S_IWUSR; |
||||
|
fdout = ::open(out.c_str(),flags,mode); |
||||
|
if(fdout == -1) |
||||
|
return -1; |
||||
|
|
||||
|
rv = fs::clonefile(fdin,fdout); |
||||
|
error = errno; |
||||
|
|
||||
|
::close(fdin); |
||||
|
::close(fdout); |
||||
|
|
||||
|
errno = error; |
||||
|
return rv; |
||||
|
} |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include <string>
|
||||
|
|
||||
|
namespace fs |
||||
|
{ |
||||
|
int clonefile(const int fdin, |
||||
|
const int fdout); |
||||
|
int clonefile(const std::string &from, |
||||
|
const std::string &to); |
||||
|
} |
@ -0,0 +1,117 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2015 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include <sys/types.h>
|
||||
|
#include <sys/stat.h>
|
||||
|
#include <unistd.h>
|
||||
|
#include <errno.h>
|
||||
|
|
||||
|
#include <string>
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
#include "fs_attr.hpp"
|
||||
|
#include "fs_xattr.hpp"
|
||||
|
|
||||
|
using std::string; |
||||
|
|
||||
|
namespace fs |
||||
|
{ |
||||
|
static |
||||
|
bool |
||||
|
ignorable_error(const int err) |
||||
|
{ |
||||
|
switch(err) |
||||
|
{ |
||||
|
case ENOTTY: |
||||
|
case ENOTSUP: |
||||
|
#if ENOTSUP != EOPNOTSUPP
|
||||
|
case EOPNOTSUPP: |
||||
|
#endif
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
clonepath(const string &fromsrc, |
||||
|
const string &tosrc, |
||||
|
const string &relative) |
||||
|
{ |
||||
|
int rv; |
||||
|
struct stat st; |
||||
|
string topath; |
||||
|
string frompath; |
||||
|
string dirname; |
||||
|
|
||||
|
dirname = fs::path::dirname(relative); |
||||
|
if(!dirname.empty()) |
||||
|
{ |
||||
|
rv = clonepath(fromsrc,tosrc,dirname); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
fs::path::make(fromsrc,relative,frompath); |
||||
|
rv = ::stat(frompath.c_str(),&st); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
else if(!S_ISDIR(st.st_mode)) |
||||
|
return (errno = ENOTDIR,-1); |
||||
|
|
||||
|
fs::path::make(tosrc,relative,topath); |
||||
|
rv = ::mkdir(topath.c_str(),st.st_mode); |
||||
|
if(rv == -1) |
||||
|
{ |
||||
|
if(errno != EEXIST) |
||||
|
return -1; |
||||
|
|
||||
|
rv = ::chmod(topath.c_str(),st.st_mode); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
// It may not support it... it's fine...
|
||||
|
rv = fs::attr::copy(frompath,topath); |
||||
|
if(rv == -1 && !ignorable_error(errno)) |
||||
|
return -1; |
||||
|
|
||||
|
rv = fs::xattr::copy(frompath,topath); |
||||
|
if(rv == -1 && !ignorable_error(errno)) |
||||
|
return -1; |
||||
|
|
||||
|
rv = ::chown(topath.c_str(),st.st_uid,st.st_gid); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
struct timespec times[2]; |
||||
|
times[0] = st.st_atim; |
||||
|
times[1] = st.st_mtim; |
||||
|
rv = ::utimensat(-1,topath.c_str(),times,0); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include <string>
|
||||
|
|
||||
|
namespace fs |
||||
|
{ |
||||
|
int clonepath(const std::string &from, |
||||
|
const std::string &to, |
||||
|
const std::string &relative); |
||||
|
} |
@ -0,0 +1,117 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include <sys/types.h>
|
||||
|
#include <sys/stat.h>
|
||||
|
#include <unistd.h>
|
||||
|
#include <fcntl.h>
|
||||
|
|
||||
|
#include <string>
|
||||
|
#include <vector>
|
||||
|
|
||||
|
#include "fs.hpp"
|
||||
|
#include "fs_path.hpp"
|
||||
|
#include "fs_clonepath.hpp"
|
||||
|
#include "fs_clonefile.hpp"
|
||||
|
|
||||
|
using std::string; |
||||
|
using std::vector; |
||||
|
|
||||
|
namespace fs |
||||
|
{ |
||||
|
int |
||||
|
movefile(const vector<string> &basepaths, |
||||
|
const char *fusepath, |
||||
|
const size_t additional_size, |
||||
|
int &origfd) |
||||
|
{ |
||||
|
int rv; |
||||
|
int fdin; |
||||
|
int fdout; |
||||
|
int fdin_flags; |
||||
|
string fusedir; |
||||
|
string fdin_path; |
||||
|
string fdout_path; |
||||
|
struct stat fdin_st; |
||||
|
|
||||
|
fdin = origfd; |
||||
|
|
||||
|
rv = fstat(fdin,&fdin_st); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
fdin_flags = fs::getfl(fdin); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
rv = fs::findonfs(basepaths,fusepath,fdin,fdin_path); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
fdin_st.st_size += additional_size; |
||||
|
rv = fs::mfs(basepaths,fdin_st.st_size,fdout_path); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
fusedir = fs::path::dirname(fusepath); |
||||
|
rv = fs::clonepath(fdin_path,fdout_path,fusedir); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
fs::path::append(fdin_path,fusepath); |
||||
|
fdin = ::open(fdin_path.c_str(),O_RDONLY); |
||||
|
if(fdin == -1) |
||||
|
return -1; |
||||
|
|
||||
|
fs::path::append(fdout_path,fusepath); |
||||
|
fdout = ::open(fdout_path.c_str(),fdin_flags|O_CREAT,fdin_st.st_mode); |
||||
|
if(fdout == -1) |
||||
|
return -1; |
||||
|
|
||||
|
rv = fs::clonefile(fdin,fdout); |
||||
|
if(rv == -1) |
||||
|
{ |
||||
|
::close(fdin); |
||||
|
::close(fdout); |
||||
|
::unlink(fdout_path.c_str()); |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
rv = ::unlink(fdin_path.c_str()); |
||||
|
if(rv == -1) |
||||
|
{ |
||||
|
::close(fdin); |
||||
|
::close(fdout); |
||||
|
::unlink(fdout_path.c_str()); |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
::close(fdin); |
||||
|
::close(origfd); |
||||
|
|
||||
|
origfd = fdout; |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
} |
@ -0,0 +1,118 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2015 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include <dirent.h>
|
||||
|
#include <sys/stat.h>
|
||||
|
#include <sys/types.h>
|
||||
|
#include <unistd.h>
|
||||
|
|
||||
|
#include <string>
|
||||
|
|
||||
|
#include "fs_path.hpp"
|
||||
|
|
||||
|
using std::string; |
||||
|
|
||||
|
namespace fs |
||||
|
{ |
||||
|
namespace path |
||||
|
{ |
||||
|
string |
||||
|
dirname(const string &path) |
||||
|
{ |
||||
|
string parent = path; |
||||
|
string::reverse_iterator i; |
||||
|
string::reverse_iterator bi; |
||||
|
|
||||
|
bi = parent.rend(); |
||||
|
i = parent.rbegin(); |
||||
|
while(*i == '/' && i != bi) |
||||
|
i++; |
||||
|
|
||||
|
while(*i != '/' && i != bi) |
||||
|
i++; |
||||
|
|
||||
|
while(*i == '/' && i != bi) |
||||
|
i++; |
||||
|
|
||||
|
parent.erase(i.base(),parent.end()); |
||||
|
|
||||
|
return parent; |
||||
|
} |
||||
|
|
||||
|
string |
||||
|
basename(const string &path) |
||||
|
{ |
||||
|
return path.substr(path.find_last_of('/')+1); |
||||
|
} |
||||
|
|
||||
|
bool |
||||
|
is_empty(const string &path) |
||||
|
{ |
||||
|
DIR *dir; |
||||
|
struct dirent *de; |
||||
|
|
||||
|
dir = ::opendir(path.c_str()); |
||||
|
if(!dir) |
||||
|
return false; |
||||
|
|
||||
|
while((de = ::readdir(dir))) |
||||
|
{ |
||||
|
const char *d_name = de->d_name; |
||||
|
|
||||
|
if(d_name[0] == '.' && |
||||
|
((d_name[1] == '\0') || |
||||
|
(d_name[1] == '.' && d_name[2] == '\0'))) |
||||
|
continue; |
||||
|
|
||||
|
::closedir(dir); |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
::closedir(dir); |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
bool |
||||
|
exists(const vector<string> &paths, |
||||
|
const string &fusepath) |
||||
|
{ |
||||
|
for(size_t i = 0, ei = paths.size(); i != ei; i++) |
||||
|
{ |
||||
|
int rv; |
||||
|
string path; |
||||
|
struct stat st; |
||||
|
|
||||
|
fs::path::make(paths[i],fusepath,path); |
||||
|
|
||||
|
rv = ::lstat(path.c_str(),&st); |
||||
|
if(rv == 0) |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,76 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __FS_PATH_HPP__
|
||||
|
#define __FS_PATH_HPP__
|
||||
|
|
||||
|
#include <string>
|
||||
|
#include <vector>
|
||||
|
|
||||
|
namespace fs |
||||
|
{ |
||||
|
namespace path |
||||
|
{ |
||||
|
using std::string; |
||||
|
using std::vector; |
||||
|
|
||||
|
string dirname(const string &path); |
||||
|
string basename(const string &path); |
||||
|
|
||||
|
bool is_empty(const string &path); |
||||
|
|
||||
|
bool exists(vector<string>::const_iterator begin, |
||||
|
vector<string>::const_iterator end, |
||||
|
const string &fusepath); |
||||
|
bool exists(const vector<string> &srcmounts, |
||||
|
const string &fusepath); |
||||
|
|
||||
|
inline |
||||
|
string |
||||
|
make(const string &base, |
||||
|
const string &suffix) |
||||
|
{ |
||||
|
return base + suffix; |
||||
|
} |
||||
|
|
||||
|
inline |
||||
|
void |
||||
|
make(const string &base, |
||||
|
const string &suffix, |
||||
|
string &output) |
||||
|
{ |
||||
|
output = base + suffix; |
||||
|
} |
||||
|
|
||||
|
inline |
||||
|
void |
||||
|
append(string &base, |
||||
|
const string &suffix) |
||||
|
{ |
||||
|
base += suffix; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
#endif // __FS_PATH_HPP__
|
@ -0,0 +1,399 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include <stdlib.h>
|
||||
|
#include <sys/types.h>
|
||||
|
#include <attr/xattr.h>
|
||||
|
#include <sys/stat.h>
|
||||
|
#include <fcntl.h>
|
||||
|
#include <unistd.h>
|
||||
|
|
||||
|
#include <string>
|
||||
|
#include <vector>
|
||||
|
#include <map>
|
||||
|
#include <sstream>
|
||||
|
|
||||
|
#include "str.hpp"
|
||||
|
#include "xattr.hpp"
|
||||
|
|
||||
|
using std::string; |
||||
|
using std::vector; |
||||
|
using std::map; |
||||
|
using std::istringstream; |
||||
|
|
||||
|
namespace fs |
||||
|
{ |
||||
|
namespace xattr |
||||
|
{ |
||||
|
int |
||||
|
list(const int fd, |
||||
|
vector<char> &attrs) |
||||
|
{ |
||||
|
#ifndef WITHOUT_XATTR
|
||||
|
ssize_t rv; |
||||
|
ssize_t size; |
||||
|
|
||||
|
rv = -1; |
||||
|
errno = ERANGE; |
||||
|
while(rv == -1 && errno == ERANGE) |
||||
|
{ |
||||
|
size = ::flistxattr(fd,NULL,0); |
||||
|
attrs.resize(size); |
||||
|
if(size == 0) |
||||
|
return 0; |
||||
|
rv = ::flistxattr(fd,&attrs[0],size); |
||||
|
} |
||||
|
|
||||
|
return rv; |
||||
|
#else
|
||||
|
errno = ENOTSUP; |
||||
|
return -1; |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
int |
||||
|
list(const string &path, |
||||
|
vector<char> &attrs) |
||||
|
{ |
||||
|
#ifndef WITHOUT_XATTR
|
||||
|
int rv; |
||||
|
int size; |
||||
|
|
||||
|
rv = -1; |
||||
|
errno = ERANGE; |
||||
|
while(rv == -1 && errno == ERANGE) |
||||
|
{ |
||||
|
size = ::listxattr(path.c_str(),NULL,0); |
||||
|
attrs.resize(size); |
||||
|
if(size == 0) |
||||
|
return 0; |
||||
|
rv = ::listxattr(path.c_str(),&attrs[0],size); |
||||
|
} |
||||
|
|
||||
|
return rv; |
||||
|
#else
|
||||
|
errno = ENOTSUP; |
||||
|
return -1; |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
int |
||||
|
list(const int fd, |
||||
|
vector<string> &attrvector) |
||||
|
{ |
||||
|
int rv; |
||||
|
vector<char> attrs; |
||||
|
|
||||
|
rv = list(fd,attrs); |
||||
|
if(rv != -1) |
||||
|
{ |
||||
|
string tmp(attrs.begin(),attrs.end()); |
||||
|
str::split(attrvector,tmp,'\0'); |
||||
|
} |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
list(const string &path, |
||||
|
vector<string> &attrvector) |
||||
|
{ |
||||
|
int rv; |
||||
|
vector<char> attrs; |
||||
|
|
||||
|
rv = list(path,attrs); |
||||
|
if(rv != -1) |
||||
|
{ |
||||
|
string tmp(attrs.begin(),attrs.end()); |
||||
|
str::split(attrvector,tmp,'\0'); |
||||
|
} |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
list(const int fd, |
||||
|
string &attrstr) |
||||
|
{ |
||||
|
int rv; |
||||
|
vector<char> attrs; |
||||
|
|
||||
|
rv = list(fd,attrs); |
||||
|
if(rv != -1) |
||||
|
attrstr = string(attrs.begin(),attrs.end()); |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
list(const string &path, |
||||
|
string &attrstr) |
||||
|
{ |
||||
|
int rv; |
||||
|
vector<char> attrs; |
||||
|
|
||||
|
rv = list(path,attrs); |
||||
|
if(rv != -1) |
||||
|
attrstr = string(attrs.begin(),attrs.end()); |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
get(const int fd, |
||||
|
const string &attr, |
||||
|
vector<char> &value) |
||||
|
{ |
||||
|
#ifndef WITHOUT_XATTR
|
||||
|
int rv; |
||||
|
int size; |
||||
|
|
||||
|
rv = -1; |
||||
|
errno = ERANGE; |
||||
|
while(rv == -1 && errno == ERANGE) |
||||
|
{ |
||||
|
size = ::fgetxattr(fd,attr.c_str(),NULL,0); |
||||
|
value.resize(size); |
||||
|
if(size == 0) |
||||
|
return 0; |
||||
|
rv = ::fgetxattr(fd,attr.c_str(),&value[0],size); |
||||
|
} |
||||
|
|
||||
|
return rv; |
||||
|
#else
|
||||
|
errno = ENOTSUP; |
||||
|
return -1; |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
int |
||||
|
get(const string &path, |
||||
|
const string &attr, |
||||
|
vector<char> &value) |
||||
|
{ |
||||
|
#ifndef WITHOUT_XATTR
|
||||
|
int rv; |
||||
|
int size; |
||||
|
|
||||
|
rv = -1; |
||||
|
errno = ERANGE; |
||||
|
while(rv == -1 && errno == ERANGE) |
||||
|
{ |
||||
|
size = ::getxattr(path.c_str(),attr.c_str(),NULL,0); |
||||
|
value.resize(size); |
||||
|
if(size == 0) |
||||
|
return 0; |
||||
|
rv = ::getxattr(path.c_str(),attr.c_str(),&value[0],size); |
||||
|
} |
||||
|
|
||||
|
return rv; |
||||
|
#else
|
||||
|
errno = ENOTSUP; |
||||
|
return -1; |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
int |
||||
|
get(const int fd, |
||||
|
const string &attr, |
||||
|
string &value) |
||||
|
{ |
||||
|
int rv; |
||||
|
vector<char> tmpvalue; |
||||
|
|
||||
|
rv = get(fd,attr,tmpvalue); |
||||
|
if(rv != -1) |
||||
|
value = string(tmpvalue.begin(),tmpvalue.end()); |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
get(const string &path, |
||||
|
const string &attr, |
||||
|
string &value) |
||||
|
{ |
||||
|
int rv; |
||||
|
vector<char> tmpvalue; |
||||
|
|
||||
|
rv = get(path,attr,tmpvalue); |
||||
|
if(rv != -1) |
||||
|
value = string(tmpvalue.begin(),tmpvalue.end()); |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
get(const int fd, |
||||
|
map<string,string> &attrs) |
||||
|
{ |
||||
|
int rv; |
||||
|
string attrstr; |
||||
|
|
||||
|
rv = list(fd,attrstr); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
{ |
||||
|
string key; |
||||
|
istringstream ss(attrstr); |
||||
|
|
||||
|
while(getline(ss,key,'\0')) |
||||
|
{ |
||||
|
string value; |
||||
|
|
||||
|
rv = get(fd,key,value); |
||||
|
if(rv != -1) |
||||
|
attrs[key] = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
get(const string &path, |
||||
|
map<string,string> &attrs) |
||||
|
{ |
||||
|
int rv; |
||||
|
string attrstr; |
||||
|
|
||||
|
rv = list(path,attrstr); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
{ |
||||
|
string key; |
||||
|
istringstream ss(attrstr); |
||||
|
|
||||
|
while(getline(ss,key,'\0')) |
||||
|
{ |
||||
|
string value; |
||||
|
|
||||
|
rv = get(path,key,value); |
||||
|
if(rv != -1) |
||||
|
attrs[key] = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
set(const int fd, |
||||
|
const string &key, |
||||
|
const string &value, |
||||
|
const int flags) |
||||
|
{ |
||||
|
#ifndef WITHOUT_XATTR
|
||||
|
return ::fsetxattr(fd, |
||||
|
key.c_str(), |
||||
|
value.data(), |
||||
|
value.size(), |
||||
|
flags); |
||||
|
#else
|
||||
|
errno = ENOTSUP; |
||||
|
return -1; |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
int |
||||
|
set(const string &path, |
||||
|
const string &key, |
||||
|
const string &value, |
||||
|
const int flags) |
||||
|
{ |
||||
|
#ifndef WITHOUT_XATTR
|
||||
|
return ::setxattr(path.c_str(), |
||||
|
key.c_str(), |
||||
|
value.data(), |
||||
|
value.size(), |
||||
|
flags); |
||||
|
#else
|
||||
|
errno = ENOTSUP; |
||||
|
return -1; |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
|
int |
||||
|
set(const int fd, |
||||
|
const map<string,string> &attrs) |
||||
|
{ |
||||
|
int rv; |
||||
|
|
||||
|
for(map<string,string>::const_iterator |
||||
|
i = attrs.begin(), ei = attrs.end(); i != ei; ++i) |
||||
|
{ |
||||
|
rv = set(fd,i->first,i->second,0); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
set(const string &path, |
||||
|
const map<string,string> &attrs) |
||||
|
{ |
||||
|
int fd; |
||||
|
|
||||
|
fd = ::open(path.c_str(),O_RDONLY|O_NONBLOCK); |
||||
|
if(fd == -1) |
||||
|
return -1; |
||||
|
|
||||
|
set(fd,attrs); |
||||
|
|
||||
|
return ::close(fd); |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
copy(const int fdin, |
||||
|
const int fdout) |
||||
|
{ |
||||
|
int rv; |
||||
|
map<string,string> attrs; |
||||
|
|
||||
|
rv = get(fdin,attrs); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
return set(fdout,attrs); |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
copy(const string &from, |
||||
|
const string &to) |
||||
|
{ |
||||
|
int rv; |
||||
|
map<string,string> attrs; |
||||
|
|
||||
|
rv = get(from,attrs); |
||||
|
if(rv == -1) |
||||
|
return -1; |
||||
|
|
||||
|
return set(to,attrs); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,78 @@ |
|||||
|
/*
|
||||
|
The MIT License (MIT) |
||||
|
|
||||
|
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link> |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in |
||||
|
all copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#ifndef __FS_XATTR_HPP__
|
||||
|
#define __FS_XATTR_HPP__
|
||||
|
|
||||
|
#include <string>
|
||||
|
#include <vector>
|
||||
|
#include <map>
|
||||
|
|
||||
|
namespace fs |
||||
|
{ |
||||
|
namespace xattr |
||||
|
{ |
||||
|
using std::size_t; |
||||
|
using std::string; |
||||
|
using std::vector; |
||||
|
using std::map; |
||||
|
|
||||
|
|
||||
|
int list(const string &path, |
||||
|
vector<char> &attrs); |
||||
|
int list(const string &path, |
||||
|
string &attrs); |
||||
|
int list(const string &path, |
||||
|
vector<string> &attrs); |
||||
|
|
||||
|
int get(const string &path, |
||||
|
const string &attr, |
||||
|
vector<char> &value); |
||||
|
int get(const string &path, |
||||
|
const string &attr, |
||||
|
string &value); |
||||
|
|
||||
|
int get(const string &path, |
||||
|
map<string,string> &attrs); |
||||
|
|
||||
|
int set(const string &path, |
||||
|
const string &key, |
||||
|
const string &value, |
||||
|
const int flags); |
||||
|
int set(const int fd, |
||||
|
const string &key, |
||||
|
const string &value, |
||||
|
const int flags); |
||||
|
|
||||
|
int set(const string &path, |
||||
|
const map<string,string> &attrs); |
||||
|
|
||||
|
int copy(const int fdin, |
||||
|
const int fdout); |
||||
|
int copy(const string &from, |
||||
|
const string &to); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endif // __FS_HPP__
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue