Implement CryOpenFile and infrastructure around it

This commit is contained in:
Sebastian Messmer 2014-11-10 22:42:17 +01:00
parent 3c34cfd6d2
commit 21f1a294ab
14 changed files with 190 additions and 13 deletions

View File

@ -29,7 +29,7 @@ CryFuse::CryFuse(CryDevice *device)
int CryFuse::getattr(const path &path, struct stat *stbuf) { int CryFuse::getattr(const path &path, struct stat *stbuf) {
try { try {
_device->LoadFromPath(path)->stat(stbuf); _device->lstat(path, stbuf);
return 0; return 0;
} catch(cryfs::CryErrnoException &e) { } catch(cryfs::CryErrnoException &e) {
return -e.getErrno(); return -e.getErrno();
@ -47,8 +47,12 @@ int CryFuse::fgetattr(const path &path, struct stat *stbuf, fuse_file_info *file
return getattr(path, stbuf); return getattr(path, stbuf);
} }
int retstat = fstat(fileinfo->fh, stbuf); try {
return errcode_map(retstat); _device->fstat(fileinfo->fh, stbuf);
return 0;
} catch(cryfs::CryErrnoException &e) {
return -e.getErrno();
}
} }
int CryFuse::readlink(const path &path, char *buf, size_t size) { int CryFuse::readlink(const path &path, char *buf, size_t size) {

View File

@ -1,3 +1,3 @@
add_library(cryfs_lib CryDevice.cpp CryDir.cpp CryErrnoException.cpp CryFile.cpp CryNode.cpp) add_library(cryfs_lib CryDevice.cpp CryDir.cpp CryErrnoException.cpp CryFile.cpp CryNode.cpp CryOpenFile.cpp CryOpenFileList.cpp)
target_link_libraries(cryfs_lib boost_filesystem) target_link_libraries(cryfs_lib boost_filesystem)

View File

@ -4,7 +4,9 @@
#include "CryDir.h" #include "CryDir.h"
#include "CryFile.h" #include "CryFile.h"
#include "CryOpenFile.h"
#include "CryErrnoException.h" #include "CryErrnoException.h"
#include "utils/pointer.h"
using namespace cryfs; using namespace cryfs;
@ -12,13 +14,13 @@ using std::unique_ptr;
using std::make_unique; using std::make_unique;
CryDevice::CryDevice(const bf::path &rootdir) CryDevice::CryDevice(const bf::path &rootdir)
:_rootdir(rootdir) { :_rootdir(rootdir), _open_files() {
} }
CryDevice::~CryDevice() { CryDevice::~CryDevice() {
} }
unique_ptr<CryNode> CryDevice::LoadFromPath(const bf::path &path) { unique_ptr<CryNode> CryDevice::Load(const bf::path &path) {
auto real_path = RootDir() / path; auto real_path = RootDir() / path;
if(bf::is_directory(real_path)) { if(bf::is_directory(real_path)) {
return make_unique<CryDir>(this, path); return make_unique<CryDir>(this, path);
@ -28,3 +30,25 @@ unique_ptr<CryNode> CryDevice::LoadFromPath(const bf::path &path) {
throw CryErrnoException(ENOENT); throw CryErrnoException(ENOENT);
} }
std::unique_ptr<CryFile> CryDevice::LoadFile(const bf::path &path) {
auto node = Load(path);
auto file = dynamic_pointer_move<CryFile>(node);
if (!file) {
throw CryErrnoException(EISDIR);
}
return file;
}
int CryDevice::OpenFile(const bf::path &path, int flags) {
auto file = LoadFile(path);
return _open_files.open(*file, flags);
}
void CryDevice::lstat(const bf::path &path, struct ::stat *stbuf) {
Load(path)->stat(stbuf);
}
void CryDevice::fstat(int descriptor, struct ::stat *stbuf) {
_open_files.get(descriptor)->stat(stbuf);
}

View File

@ -3,11 +3,15 @@
#define CRYFS_LIB_CRYDEVICE_H_ #define CRYFS_LIB_CRYDEVICE_H_
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include "utils/macros.h" #include <cryfs_lib/CryOpenFileList.h>
#include <memory> #include <memory>
#include <sys/stat.h>
#include "utils/macros.h"
namespace cryfs { namespace cryfs {
class CryNode; class CryNode;
class CryFile;
namespace bf = boost::filesystem; namespace bf = boost::filesystem;
@ -16,12 +20,16 @@ public:
CryDevice(const bf::path &rootdir); CryDevice(const bf::path &rootdir);
virtual ~CryDevice(); virtual ~CryDevice();
std::unique_ptr<CryNode> LoadFromPath(const bf::path &path); int OpenFile(const bf::path &path, int flags);
//std::unique_ptr<const CryNode> LoadFromPath(const bf::path &path) const; void lstat(const bf::path &path, struct ::stat *stbuf);
void fstat(int descriptor, struct ::stat *stbuf);
const bf::path &RootDir() const; const bf::path &RootDir() const;
private: private:
std::unique_ptr<CryNode> Load(const bf::path &path);
std::unique_ptr<CryFile> LoadFile(const bf::path &path);
const bf::path _rootdir; const bf::path _rootdir;
CryOpenFileList _open_files;
DISALLOW_COPY_AND_ASSIGN(CryDevice); DISALLOW_COPY_AND_ASSIGN(CryDevice);
}; };

View File

@ -3,6 +3,7 @@
#define CRYFS_LIB_CRYDIR_H_ #define CRYFS_LIB_CRYDIR_H_
#include "CryNode.h" #include "CryNode.h"
#include "utils/macros.h"
namespace cryfs { namespace cryfs {
class CryDevice; class CryDevice;
@ -11,6 +12,8 @@ class CryDir: public CryNode {
public: public:
CryDir(CryDevice *device, const bf::path &path); CryDir(CryDevice *device, const bf::path &path);
virtual ~CryDir(); virtual ~CryDir();
private:
DISALLOW_COPY_AND_ASSIGN(CryDir);
}; };
} /* namespace cryfs */ } /* namespace cryfs */

View File

@ -1,5 +1,8 @@
#include "CryFile.h" #include "CryFile.h"
#include "CryErrnoException.h" #include "CryOpenFile.h"
using std::unique_ptr;
using std::make_unique;
namespace cryfs { namespace cryfs {
@ -10,4 +13,8 @@ CryFile::CryFile(CryDevice *device, const bf::path &path)
CryFile::~CryFile() { CryFile::~CryFile() {
} }
std::unique_ptr<CryOpenFile> CryFile::open(int flags) const {
return make_unique<CryOpenFile>(base_path(), flags);
}
} /* namespace cryfs */ } /* namespace cryfs */

View File

@ -6,13 +6,19 @@
#include "CryDevice.h" #include "CryDevice.h"
#include "CryNode.h" #include "CryNode.h"
#include "utils/macros.h"
namespace cryfs { namespace cryfs {
class CryOpenFile;
class CryFile: public CryNode { class CryFile: public CryNode {
public: public:
CryFile(CryDevice *device, const bf::path &path); CryFile(CryDevice *device, const bf::path &path);
virtual ~CryFile(); virtual ~CryFile();
std::unique_ptr<CryOpenFile> open(int flags) const;
private:
DISALLOW_COPY_AND_ASSIGN(CryFile);
}; };
} /* namespace cryfs */ } /* namespace cryfs */

View File

@ -12,7 +12,7 @@ CryNode::CryNode(CryDevice *device, const bf::path &path)
CryNode::~CryNode() { CryNode::~CryNode() {
} }
void CryNode::stat(struct stat *result) const { void CryNode::stat(struct ::stat *result) const {
int retval = ::lstat(base_path().c_str(), result); int retval = ::lstat(base_path().c_str(), result);
CHECK_RETVAL(retval); CHECK_RETVAL(retval);
} }

View File

@ -17,11 +17,10 @@ public:
CryNode(CryDevice *device, const bf::path &path); CryNode(CryDevice *device, const bf::path &path);
virtual ~CryNode(); virtual ~CryNode();
void stat(struct stat *result) const; void stat(struct ::stat *result) const;
protected: protected:
bf::path base_path() const; bf::path base_path() const;
CryDevice *device();
private: private:
CryDevice *const _device; CryDevice *const _device;

View File

@ -0,0 +1,24 @@
#include <cryfs_lib/CryOpenFile.h>
#include <sys/types.h>
#include <fcntl.h>
#include "CryErrnoException.h"
using namespace cryfs;
CryOpenFile::CryOpenFile(const bf::path &path, int flags)
:_descriptor(::open(path.c_str(), flags)) {
CHECK_RETVAL(_descriptor);
}
CryOpenFile::~CryOpenFile() {
int retval = close(_descriptor);
CHECK_RETVAL(retval);
}
void CryOpenFile::stat(struct ::stat *result) const {
int retval = ::fstat(_descriptor, result);
CHECK_RETVAL(retval);
}

View File

@ -0,0 +1,27 @@
#ifndef CRYFS_LIB_CRYOPENFILE_H_
#define CRYFS_LIB_CRYOPENFILE_H_
#include <boost/filesystem.hpp>
#include <sys/stat.h>
#include "utils/macros.h"
namespace cryfs {
namespace bf = boost::filesystem;
class CryOpenFile {
public:
CryOpenFile(const bf::path &path, int flags);
virtual ~CryOpenFile();
void stat(struct ::stat *result) const;
private:
int _descriptor;
DISALLOW_COPY_AND_ASSIGN(CryOpenFile);
};
}
#endif /* CRYFS_LIB_CRYOPENFILE_H_ */

View File

@ -0,0 +1,28 @@
#include <cryfs_lib/CryOpenFileList.h>
#include "CryFile.h"
#include "CryOpenFile.h"
using namespace cryfs;
CryOpenFileList::CryOpenFileList()
:_open_files() {
}
CryOpenFileList::~CryOpenFileList() {
}
int CryOpenFileList::open(const CryFile &file, int flags) {
//TODO Reuse descriptors
int desc = _open_files.size();
_open_files[desc] = file.open(flags);
return desc;
}
CryOpenFile *CryOpenFileList::get(int descriptor) {
return _open_files.at(descriptor).get();
}
void CryOpenFileList::close(int descriptor) {
//The destructor of the stored CryFile::OpenFile closes the file
_open_files.erase(descriptor);
}

View File

@ -0,0 +1,29 @@
#ifndef CRYFS_LIB_CRYOPENFILELIST_H_
#define CRYFS_LIB_CRYOPENFILELIST_H_
#include <map>
#include <memory>
#include "utils/macros.h"
namespace cryfs {
class CryFile;
class CryOpenFile;
class CryOpenFileList {
public:
CryOpenFileList();
virtual ~CryOpenFileList();
int open(const CryFile &rhs, int flags);
CryOpenFile *get(int descriptor);
void close(int descriptor);
private:
std::map<int, std::unique_ptr<CryOpenFile>> _open_files;
DISALLOW_COPY_AND_ASSIGN(CryOpenFileList);
};
}
#endif /* CRYFS_LIB_CRYOPENFILELIST_H_ */

View File

@ -0,0 +1,18 @@
#pragma once
#ifndef CRYFS_LIB_UTILS_POINTER_H_
#define CRYFS_LIB_UTILS_POINTER_H_
#include <memory>
namespace cryfs {
template<typename DST, typename SRC>
inline std::unique_ptr<DST> dynamic_pointer_move(std::unique_ptr<SRC> &source) {
DST *casted = dynamic_cast<DST*>(source.get());
if (casted != nullptr) {
source.release();
}
return std::unique_ptr<DST>(casted);
}
}
#endif