mirror of
https://github.com/ksherlock/profuse.git
synced 2025-01-21 16:30:47 +00:00
new branch to integrate BlockDevice, BlockCache
git-svn-id: https://profuse.googlecode.com/svn/branches/profuse_interim@334 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
parent
5427db9990
commit
c82cd3f8fa
128
File/File.cpp
Normal file
128
File/File.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
|
||||
#include <File/File.h>
|
||||
#include <ProFUSE/Exception.h>
|
||||
|
||||
|
||||
|
||||
using ProFUSE::Exception;
|
||||
using ProFUSE::POSIXException;
|
||||
|
||||
|
||||
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, const std::nothrow_t&)
|
||||
{
|
||||
_fd = ::open(name, flags);
|
||||
}
|
||||
|
||||
|
||||
File::File(const char *name, int flags, mode_t mode, const std::nothrow_t&)
|
||||
{
|
||||
_fd = ::open(name, flags, mode);
|
||||
}
|
||||
|
||||
File::File(const char *name, FileFlags flags, const std::nothrow_t&)
|
||||
{
|
||||
_fd = ::open(name, flags == ReadOnly ? O_RDONLY : O_RDWR);
|
||||
}
|
||||
|
||||
File::File(const char *name, int flags)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "File::File"
|
||||
|
||||
_fd = ::open(name, flags);
|
||||
if (_fd < 0)
|
||||
throw POSIXException( __METHOD__ ": open", errno);
|
||||
}
|
||||
|
||||
File::File(const char *name, int flags, mode_t mode)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "File::File"
|
||||
|
||||
_fd = ::open(name, flags, mode);
|
||||
if (_fd < 0)
|
||||
throw POSIXException( __METHOD__ ": open", errno);
|
||||
}
|
||||
|
||||
|
||||
File::File(const char *name, FileFlags flags)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "File::File"
|
||||
|
||||
_fd = ::open(name, flags == ReadOnly ? O_RDONLY : O_RDWR);
|
||||
if (_fd < 0)
|
||||
throw POSIXException( __METHOD__ ": open", errno);
|
||||
}
|
||||
|
||||
|
||||
File::~File()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
int File::release()
|
||||
{
|
||||
int tmp = _fd;
|
||||
_fd = -1;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void File::close()
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "File::close"
|
||||
|
||||
if (_fd >= 0)
|
||||
{
|
||||
::close(_fd);
|
||||
_fd = -1;
|
||||
|
||||
// destructor shouldn't throw.
|
||||
/*
|
||||
if (::close(fd) != 0)
|
||||
throw POSIXException(__METHOD__ ": close", errno);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void File::adopt(File &f)
|
||||
{
|
||||
if (&f == this) return;
|
||||
|
||||
close();
|
||||
_fd = f._fd;
|
||||
f._fd = -1;
|
||||
}
|
||||
|
||||
void File::adopt(int fd)
|
||||
{
|
||||
if (fd == _fd) return;
|
||||
close();
|
||||
_fd = fd;
|
||||
}
|
||||
|
||||
|
||||
void File::swap(File &f)
|
||||
{
|
||||
std::swap(_fd, f._fd);
|
||||
}
|
58
File/File.h
Normal file
58
File/File.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef __FILE_H__
|
||||
#define __FILE_H__
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
|
||||
class File {
|
||||
|
||||
public:
|
||||
|
||||
enum FileFlags {
|
||||
ReadOnly = 1,
|
||||
ReadWrite = 2
|
||||
};
|
||||
|
||||
File();
|
||||
File(File &);
|
||||
File(int fd);
|
||||
|
||||
File(const char *name, int flags);
|
||||
File(const char *name, int flags, mode_t mode);
|
||||
File(const char *name, FileFlags flags);
|
||||
|
||||
File(const char *name, int flags, const std::nothrow_t &);
|
||||
File(const char *name, int flags, mode_t mode, const std::nothrow_t &);
|
||||
File(const char *name, FileFlags flags, const std::nothrow_t &);
|
||||
|
||||
~File();
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return _fd >= 0;
|
||||
}
|
||||
|
||||
int fd() const { return _fd; }
|
||||
|
||||
int release();
|
||||
|
||||
void close();
|
||||
|
||||
void adopt(File &f);
|
||||
void adopt(int fd);
|
||||
|
||||
void swap(File &f);
|
||||
|
||||
private:
|
||||
|
||||
// could call dup() or something.
|
||||
File& operator=(const File &f);
|
||||
int _fd;
|
||||
};
|
||||
|
||||
#endif
|
187
File/MappedFile.cpp
Normal file
187
File/MappedFile.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <File/MappedFile.h>
|
||||
#include <ProFUSE/Exception.h>
|
||||
|
||||
|
||||
using ProFUSE::POSIXException;
|
||||
|
||||
MappedFile::MappedFile()
|
||||
{
|
||||
_length = -1;
|
||||
_address = MAP_FAILED;
|
||||
_readOnly = true;
|
||||
}
|
||||
|
||||
MappedFile::MappedFile(MappedFile &mf)
|
||||
{
|
||||
_address = mf._address;
|
||||
_length = mf._length;
|
||||
_readOnly = mf._readOnly;
|
||||
|
||||
mf._address = MAP_FAILED;
|
||||
mf._length = -1;
|
||||
mf._readOnly = true;
|
||||
}
|
||||
|
||||
MappedFile::MappedFile(const File &f, File::FileFlags flags, size_t size)
|
||||
{
|
||||
_length = -1;
|
||||
_address = MAP_FAILED;
|
||||
_readOnly = true;
|
||||
|
||||
init(f, flags == File::ReadOnly, size);
|
||||
}
|
||||
|
||||
|
||||
MappedFile::MappedFile(const char *name, File::FileFlags flags)
|
||||
{
|
||||
File f(name, flags);
|
||||
|
||||
_length = -1;
|
||||
_address = MAP_FAILED;
|
||||
_readOnly = true;
|
||||
|
||||
init(f, flags == File::ReadOnly, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
MappedFile::MappedFile(const char *name, File::FileFlags flags, const std::nothrow_t ¬hrow)
|
||||
{
|
||||
File f(name, flags, nothrow);
|
||||
|
||||
_length = -1;
|
||||
_address = MAP_FAILED;
|
||||
_readOnly = true;
|
||||
|
||||
if (f.isValid())
|
||||
init(f, flags == File::ReadOnly, 0);
|
||||
}
|
||||
|
||||
|
||||
MappedFile::~MappedFile()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MappedFile::init(const File &f, bool readOnly, size_t size)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "MappedFile::init"
|
||||
|
||||
struct stat st;
|
||||
int prot = readOnly ? PROT_READ : PROT_READ | PROT_WRITE;
|
||||
int flags = MAP_FILE | MAP_SHARED;
|
||||
|
||||
// close enough
|
||||
if (f.fd() < 0)
|
||||
throw POSIXException( __METHOD__, EBADF);
|
||||
|
||||
|
||||
if (!size)
|
||||
{
|
||||
if (::fstat(f.fd(), &st) != 0)
|
||||
throw POSIXException(__METHOD__ ": fstat", errno);
|
||||
|
||||
if (!S_ISREG(st.st_mode))
|
||||
throw POSIXException(__METHOD__, ENODEV);
|
||||
|
||||
size = st.st_size;
|
||||
}
|
||||
|
||||
_length = size;
|
||||
_address = ::mmap(0, _length, prot, flags, f.fd(), 0);
|
||||
|
||||
if (_address == MAP_FAILED)
|
||||
throw POSIXException(__METHOD__ ": mmap", errno);
|
||||
|
||||
_readOnly = readOnly;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MappedFile::close()
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "MappedFile::close"
|
||||
|
||||
if (_address != MAP_FAILED)
|
||||
{
|
||||
/*
|
||||
void *address = _address;
|
||||
size_t length = _length;
|
||||
*/
|
||||
|
||||
::munmap(_address, _length);
|
||||
|
||||
_address = MAP_FAILED;
|
||||
_length = -1;
|
||||
_readOnly = true;
|
||||
|
||||
// destructor shouldn't throw.
|
||||
/*
|
||||
if (::munmap(address, length) != 0)
|
||||
throw POSIXException(__METHOD__ ": munmap", errno);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void MappedFile::sync()
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "MappedFile::sync"
|
||||
|
||||
if (_address != MAP_FAILED)
|
||||
{
|
||||
if (::msync(_address, _length, MS_SYNC) != 0)
|
||||
throw POSIXException(__METHOD__ ": msync", errno);
|
||||
}
|
||||
}
|
||||
|
||||
void MappedFile::adopt(MappedFile &mf)
|
||||
{
|
||||
close();
|
||||
_address = mf._address;
|
||||
_length = mf._length;
|
||||
_readOnly = mf._readOnly;
|
||||
|
||||
mf._address = MAP_FAILED;
|
||||
mf._length = -1;
|
||||
mf._readOnly = true;
|
||||
}
|
||||
|
||||
void MappedFile::swap(MappedFile &mf)
|
||||
{
|
||||
std::swap(_address, mf._address);
|
||||
std::swap(_length, mf._length);
|
||||
std::swap(_readOnly, mf._readOnly);
|
||||
}
|
||||
|
||||
|
||||
MappedFile *MappedFile::Create(const char *name, size_t size)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "MappedFile::Create"
|
||||
|
||||
File fd(::open(name, O_CREAT | O_TRUNC | O_RDWR, 0644));
|
||||
|
||||
if (!fd.isValid())
|
||||
{
|
||||
throw POSIXException(__METHOD__ ": Unable to create file.", errno);
|
||||
}
|
||||
|
||||
// TODO -- is ftruncate portable?
|
||||
if (::ftruncate(fd.fd(), size) < 0)
|
||||
{
|
||||
// TODO -- unlink?
|
||||
throw POSIXException(__METHOD__ ": Unable to truncate file.", errno);
|
||||
}
|
||||
|
||||
return new MappedFile(fd, File::ReadWrite, size);
|
||||
}
|
53
File/MappedFile.h
Normal file
53
File/MappedFile.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef __MAPPED_FILE_H__
|
||||
#define __MAPPED_FILE_H__
|
||||
|
||||
|
||||
#include <new>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <File/File.h>
|
||||
|
||||
class File;
|
||||
|
||||
class MappedFile {
|
||||
public:
|
||||
|
||||
MappedFile();
|
||||
MappedFile(MappedFile&);
|
||||
MappedFile(const File &f, File::FileFlags flags, size_t size = -1);
|
||||
MappedFile(const char *name, File::FileFlags flags);
|
||||
MappedFile(const char *name, File::FileFlags flags, const std::nothrow_t ¬hrow);
|
||||
|
||||
~MappedFile();
|
||||
|
||||
|
||||
static MappedFile *Create(const char *name, size_t size);
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return _address != MAP_FAILED;
|
||||
}
|
||||
|
||||
void sync();
|
||||
void close();
|
||||
|
||||
void *address() const { return _address; }
|
||||
size_t length() const { return _length; }
|
||||
bool readOnly() const { return _readOnly; }
|
||||
|
||||
void swap(MappedFile &);
|
||||
void adopt(MappedFile &);
|
||||
|
||||
private:
|
||||
|
||||
MappedFile& operator=(MappedFile &);
|
||||
|
||||
void init(const File &f, bool readOnly, size_t size);
|
||||
|
||||
void *_address;
|
||||
size_t _length;
|
||||
bool _readOnly;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user