diff --git a/.gitignore b/.gitignore index d3a1446..0324843 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ +# Build +build/ + +# Visual Studio + +# CLion +.idea/ + # Windows image file caches Thumbs.db ehthumbs.db @@ -44,3 +52,10 @@ bin/ Network Trash Folder Temporary Items .apdisk +*.suo +*.opensdf +VFS.sdf +*.sln +VFS.vcxproj +*.user +VFS.vcxproj.filters diff --git a/CMakeLists.txt b/CMakeLists.txt index 66438f9..9c02ca0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 2.8.5) project(VFS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb3 -std=c++11") set(CMAKE_CXX "clang++") diff --git a/fs-descriptor.h b/fs-descriptor.h index a35a93d..29facd4 100644 --- a/fs-descriptor.h +++ b/fs-descriptor.h @@ -74,6 +74,33 @@ struct FileDescriptor { return length; } + virtual long long read( utils::Vector< std::pair< char *, size_t > > &buf ) { + if (!_inode) + throw Error( EBADF ); + if (!_flags.has( flags::Open::Read )) + throw Error( EBADF ); + + File *file = _inode->data()->as< File >(); + if (!file) + throw Error( EBADF ); + if (_flags.has( flags::Open::NonBlock ) && !file->canRead()) + throw Error( EAGAIN ); + + long long length = 0; //combined length of all members of buf + for ( auto & dst : buf ) { + size_t originalLengthBuf = dst.second; + if ( !file->read( dst.first, _offset, dst.second )) + throw Error( EBADF ); + length += dst.second; + _setOffset( _offset + dst.second ); + if (dst.second < originalLengthBuf) { //nothing left to read + break; + } + } + + return length; + } + virtual long long write( const void *buf, size_t length ) { if ( !_inode ) throw Error( EBADF ); @@ -97,6 +124,33 @@ struct FileDescriptor { return length; } + virtual long long write( utils::Vector< std::pair< const char *, size_t > > &buf) { + if (!_inode) + throw Error( EBADF ); + if (!_flags.has( flags::Open::Write )) + throw Error( EBADF ); + + File *file = _inode->data()->as< File >(); + if (!file) + throw Error( EBADF ); + if (_flags.has( flags::Open::NonBlock ) && !file->canWrite()) + throw Error( EAGAIN ); + + if (_flags.has( flags::Open::Append )) + _offset = file->size(); + + long long length = 0; + for (auto & src : buf) { + if (!file->write( src.first, _offset, src.second )) { + throw Error( EBADF ); + } + _setOffset( _offset + src.second ); + length += src.second; + } + + return length; + } + size_t offset() const { return _offset; } diff --git a/fs-file.h b/fs-file.h index 0061df7..2a1904e 100644 --- a/fs-file.h +++ b/fs-file.h @@ -35,7 +35,7 @@ struct Link : DataItem { }; struct File : DataItem { - + //TODO lower: write documentation virtual bool read( char *, size_t, size_t & ) = 0; virtual bool write( const char *, size_t, size_t & ) = 0; @@ -72,18 +72,20 @@ struct RegularFile : File { bool canWrite() const override { return true; } - + bool read( char *buffer, size_t offset, size_t &length ) override { if ( offset >= _size ) { length = 0; return true; } - const char *source = _isSnapshot() ? + const char *source = _isSnapshot() ? //copy on write _roContent + offset : _content.data() + offset; + if ( offset + length > _size ) length = _size - offset; std::copy( source, source + length, buffer ); + return true; } diff --git a/fs.cpp b/fs.cpp index fc37259..3c685fc 100644 --- a/fs.cpp +++ b/fs.cpp @@ -236,7 +236,7 @@ ssize_t write( int fd, const void *buf, size_t count ) { return -1; } } -ssize_t pwrite( int fd, const void *buf, size_t count, off_t offset ) { +ssize_t pwrite( int fd, const void *buf, size_t count, off_t offset ) { //TODO this FS_ENTRYPOINT(); try { auto f = vfs.instance().getFile( fd ); @@ -258,7 +258,7 @@ ssize_t read( int fd, void *buf, size_t count ) { return -1; } } -ssize_t pread( int fd, void *buf, size_t count, off_t offset ) { +ssize_t pread( int fd, void *buf, size_t count, off_t offset ) { //TODO this FS_ENTRYPOINT(); try { auto f = vfs.instance().getFile( fd );