First official checkin.
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"
23 File::File (const char *filename, bool writeable, bool create) throw(Error)
24 :_fd(_check( ::open(filename, writeable ?(create ?O_RDWR|O_CREAT :O_RDWR) :O_RDONLY, 0644) )),
29 File::File (const char *filename, int oflag) throw(Error)
30 :_fd(_check( ::open(filename, oflag, 0644) )),
32 _locked( (oflag | O_EXLOCK) ?1 :0)
42 off_t File::length() const throw(Error) {
44 _check( ::fstat(_fd,&s) );
48 void File::setLength (off_t length) throw(Error) {
49 _check( ftruncate(_fd,length) );
52 off_t File::position() const throw(Error) {
53 return _check( lseek(_fd,0,SEEK_CUR) );
56 void File::setPosition (off_t pos) throw(Error) {
57 _check( lseek(_fd,pos,SEEK_SET) );
60 off_t File::setPositionToEnd (off_t bytesBefore) throw(Error) {
61 return _check( lseek(_fd,-bytesBefore,SEEK_END) );
64 void File::read (void *dst, size_t size) throw(Error) {
65 _checkRead( ::read(_fd, dst, size), size );
68 size_t File::write (const void *src, size_t size) throw(Error) {
69 return _check( ::write(_fd, src, size) );
73 void File::readFrom (off_t where, void *dst, size_t size) throw(Error) {
74 _checkRead( ::pread(_fd, dst, size, where), size );
77 void File::writeTo (off_t where, const void *src, size_t size) throw(Error) {
78 _check( ::pwrite(_fd, src, size, where) );
81 size_t File::writeMultiple (Blob blobs[], int count) throw(Error) {
82 struct iovec vec[count];
83 for (int i=0; i<count; i++) {
84 vec[i].iov_base = (void*) blobs[i].bytes;
85 vec[i].iov_len = blobs[i].length;
87 return _check( ::writev(_fd, vec, count) );
90 size_t File::writePadding (int alignment) {
91 off_t pad = alignment - (position() & (alignment-1));
96 return write(zero, pad);
100 void File::flush() throw(Error) {
101 _check( ::fsync(_fd) );
104 void File::flushDisk() throw(Error) {
105 _check( ::fcntl(_fd,F_FULLFSYNC) );
108 bool File::hasPath (const char *path) const throw(Error) {
109 struct stat myStat, pathStat;
110 _check( ::fstat(_fd, &myStat) );
111 if ( ::stat(path, &pathStat) != 0 ) {
116 // Compare my inode number with that of the file at path:
117 return myStat.st_ino == pathStat.st_ino;
121 void File::unlink (const char *filename) throw(Error) {
122 _check( ::unlink(filename) );
125 void File::rename (const char *srcFilename, const char *dstFilename) throw(Error) {
126 _check( ::rename(srcFilename, dstFilename) );
131 #pragma mark UTILITIES:
133 int File::_check (int result) throw(Error) {
136 //printf("*** File::_check: Error %i: %s\n", errno, strerror(errno));
137 throw Error(errno, strerror(errno));
140 void File::_checkRead (ssize_t result, size_t expectedSize) throw(Error) {
141 if ((size_t)result < expectedSize) {
143 throw Error(errno, strerror(errno));
145 throw Error(kEOF, "unexpected EOF");
149 File::Error::Error(const char *m)
158 bool File::_lock (bool block) {
165 if (::flock(_fd, mode) == 0)
167 else if (errno != EWOULDBLOCK) // may be returned in LOCK_UN mode
173 void File::_unlock() {
176 ::flock(_fd, LOCK_UN);
180 File::Lock::Lock (File *file, bool block) throw(Error)
182 _locked( _file->_lock(block) )
185 File::Lock::~Lock() {
190 bool File::Lock::retry() {
192 _locked = _file->_lock(false);
198 #pragma mark MEMORY MAP:
200 MemoryMap* File::map() {
202 _memoryMap = new MemoryMap(this);
206 void File::mapRegion (off_t position, size_t length) {
207 return map()->mapRegion(position,length);
210 const void* File::mappedPosition (off_t position) const {
211 return map()->mappedPosition(position);