diff --git a/File/File.cpp b/File/File.cpp new file mode 100644 index 0000000..c036633 --- /dev/null +++ b/File/File.cpp @@ -0,0 +1,43 @@ +#include "File.h" + +#include + +using namespace File; + +File::File() +{ + _fd = -1; +} + +File::File(int fd) +{ + _fd = fd; +} + +File::File(File& f) +{ + _fd = f._fd; + f._fd = -1; +} + +File::File(const char *name, int flags) +{ + _fd = ::open(name, flags); + if (_fd < 0) + throw ProFUSE::PosixException(errno); +} + +File::~File() +{ + close(); +} + +File::close() +{ + int fd = _fd; + _fd = -1; + + if (fd >= 0 && ::close(fd) != 0) + throw ProFUSE::PosixException(errno); +} + diff --git a/File/File.h b/File/File.h new file mode 100644 index 0000000..4c766d2 --- /dev/null +++ b/File/File.h @@ -0,0 +1,33 @@ +#ifndef __FILE_H__ +#define __FILE_H__ + +#include +#include + +namespace File { + +enum Flags { + ReadOnly = O_RDONLY, + WriteOnly = O_WRONLY, + ReadWrite = O_RDWR +}; + +class File { + + public: + File(); + File(File &); + File(int fd); + File(const char *name, int flags); + ~File(); + + int fd() const { return _fd; } + + void close(); + + private: + int _fd; +}; + +} +#endif diff --git a/File/MappedFile.cpp b/File/MappedFile.cpp new file mode 100644 index 0000000..8fc4351 --- /dev/null +++ b/File/MappedFile.cpp @@ -0,0 +1,77 @@ +#include "MappedFile.h" + +#include +#include + +using namespace File; + + +MappedFile::MappedFile() +{ + _length = -1; + _address = MAP_FAILED; +} + +MappedFile::MappedFile(MappedFile &mf) +{ + _address = mf._address; + _length = mf._length; + + mf._address = MAP_FAILED; + mf._length = -1; +} + +MappedFile::MappedFile(File f, int flags) +{ + struct stat st; + + // close enough + if (f.fd() < 0) + throw ProFUSE::PosixException(EBADF); + + + if (::fstat(f.fd(), st) != 0) + throw ProFUSE::PosixException(errno); + + if (!S_ISREG(st.st_mode)) + throw ProFUSE::PosixException(ENODEV); + + _length = st.st_size; + _address = ::mmap(0, _length, + readOnly ? PROT_READ : PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, f.fd(), 0); + + if (_address == MAP_FAILED) + throw ProFUSE::PosixException(errno); +} + +MappedFile::~MappedFile() +{ + close(); +} + + + +MappedFile::close() +{ + if (_address != MAP_FAILED) + { + void *address = _address; + size_t length = _length; + + _address = MAP_FAILED; + _length = -1; + + if (::munmap(address, length) != 0) + throw ProFUSE::PosixException(errno); + } +} + +MappedFile::sync() +{ + if (_address != MAP_FAILED) + { + if (::msync(_address, _length, MS_SYNC) != 0) + throw ProFUSE::PosixException(errno); + } +} \ No newline at end of file diff --git a/File/MappedFile.h b/File/MappedFile.h new file mode 100644 index 0000000..90852ec --- /dev/null +++ b/File/MappedFile.h @@ -0,0 +1,33 @@ +#ifndef __MAPPED_FILE_H__ +#define __MAPPED_FILE_H__ + +#include + +#include "File.h" + +namespace File { + +class MappedFile { + public: + + MappedFile(); + MappedFile(File f, int flags); + MappedFile(MappedFile&); + + ~MappedFile(); + + void sync(); + void close(); + + void *address() const { return _address; } + size_t length() const { return _length; } + + private: + + void *_address; + size_t _length; +}; + +} + +#endif \ No newline at end of file