jbm: it compiles... but bombs in unit tests
5 * Created by Jens Alfke on 8/20/09.
6 * Copyright 2009 Jens Alfke. All rights reserved.
7 * BSD-Licensed: See the file "LICENSE.txt" for details.
11 #include "MemoryMap.h"
24 File::File (const char *filename, bool writeable, bool create) throw(Error)
25 :_fd(_check( ::open(filename, writeable ?(create ?O_RDWR|O_CREAT :O_RDWR) :O_RDONLY, 0644) )),
30 File::File (const char *filename, int oflag, bool locked) throw(Error)
32 :_fd(_check( ::open(filename, oflag | (locked ? O_EXLOCK : 0), 0644) )),
34 :_fd(_check( ::open(filename, oflag, 0644) )),
37 _locked( locked ? 1 : 0)
40 _check( ::flock(_fd, LOCK_EX) );
51 off_t File::length() const throw(Error) {
53 _check( ::fstat(_fd,&s) );
57 void File::setLength (off_t length) throw(Error) {
58 _check( ftruncate(_fd,length) );
61 off_t File::position() const throw(Error) {
62 return _check( lseek(_fd,0,SEEK_CUR) );
65 void File::setPosition (off_t pos) throw(Error) {
66 _check( lseek(_fd,pos,SEEK_SET) );
69 off_t File::setPositionToEnd (off_t bytesBefore) throw(Error) {
70 return _check( lseek(_fd,-bytesBefore,SEEK_END) );
73 void File::read (void *dst, size_t size) throw(Error) {
74 _checkRead( ::read(_fd, dst, size), size );
77 size_t File::write (const void *src, size_t size) throw(Error) {
78 return _check( ::write(_fd, src, size) );
82 void File::readFrom (off_t where, void *dst, size_t size) throw(Error) {
83 _checkRead( ::pread(_fd, dst, size, where), size );
86 void File::writeTo (off_t where, const void *src, size_t size) throw(Error) {
87 _check( ::pwrite(_fd, src, size, where) );
90 size_t File::writeMultiple (Blob blobs[], int count) throw(Error) {
91 struct iovec vec[count];
92 for (int i=0; i<count; i++) {
93 vec[i].iov_base = (void*) blobs[i].bytes;
94 vec[i].iov_len = blobs[i].length;
96 return _check( ::writev(_fd, vec, count) );
99 size_t File::writePadding (int alignment) {
100 int pad = alignment - (int)(position() & (alignment-1));
101 if (pad == alignment)
104 memset(zero, 0, pad);
105 return write(zero, pad);
109 void File::flush() throw(Error) {
110 _check( ::fsync(_fd) );
113 void File::flushDisk() throw(Error) {
115 _check( ::fcntl(_fd,F_FULLFSYNC) );
117 _check( fsync(_fd) );
121 bool File::hasPath (const char *path) const throw(Error) {
122 struct stat myStat, pathStat;
123 _check( ::fstat(_fd, &myStat) );
124 if ( ::stat(path, &pathStat) != 0 ) {
129 // Compare my inode number with that of the file at path:
130 return myStat.st_ino == pathStat.st_ino;
134 void File::unlink (const char *filename) throw(Error) {
135 _check( ::unlink(filename) );
138 void File::rename (const char *srcFilename, const char *dstFilename) throw(Error) {
139 _check( ::rename(srcFilename, dstFilename) );
144 #pragma mark UTILITIES:
146 int File::_check (int result) throw(Error) {
149 //printf("*** File::_check: Error %i: %s\n", errno, strerror(errno));
150 throw Error(errno, strerror(errno));
153 void File::_checkRead (ssize_t result, size_t expectedSize) throw(Error) {
154 if ((size_t)result < expectedSize) {
156 throw Error(errno, strerror(errno));
158 throw Error(kEOF, "unexpected EOF");
162 File::Error::Error(const char *m)
171 bool File::_lock (bool block) {
178 if (::flock(_fd, mode) == 0)
180 else if (errno != EWOULDBLOCK) // may be returned in LOCK_UN mode
186 void File::_unlock() {
189 ::flock(_fd, LOCK_UN);
193 File::Lock::Lock (File *file, bool block) throw(Error)
195 _locked( _file->_lock(block) )
198 File::Lock::~Lock() {
203 bool File::Lock::retry() {
205 _locked = _file->_lock(false);
211 #pragma mark MEMORY MAP:
213 MemoryMap* File::map() {
215 _memoryMap = new MemoryMap(this);
219 void File::mapRegion (off_t position, size_t length) {
220 return map()->mapRegion(position,length);
223 const void* File::mappedPosition (off_t position) const {
224 return map()->mappedPosition(position);