From 228605dc7bfac86604166d5e3bbabb72ae40b78b Mon Sep 17 00:00:00 2001 From: Björn Stenberg Date: Mon, 11 Nov 2002 13:57:58 +0000 Subject: Added support for O_RDWR and lseek() while writing. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2826 a1c6a512-1295-4272-9138-f99709370657 --- firmware/common/file.c | 52 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/firmware/common/file.c b/firmware/common/file.c index d86609e470..b86938007b 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c @@ -38,11 +38,12 @@ struct filedesc { unsigned char cache[SECTOR_SIZE]; int cacheoffset; - unsigned int fileoffset; + int fileoffset; int size; struct fat_file fatfile; bool busy; bool write; + bool dirty; }; static struct filedesc openfiles[MAX_OPEN_FILES]; @@ -85,6 +86,7 @@ int open(const char* pathname, int flags) openfiles[fd].write = false; break; + case O_RDWR: case O_WRONLY: openfiles[fd].write = true; break; @@ -168,7 +170,7 @@ int close(int fd) } if (openfiles[fd].write) { /* flush sector cache */ - if ( openfiles[fd].cacheoffset != -1 ) { + if ( openfiles[fd].dirty ) { if ( fat_readwrite(&(openfiles[fd].fatfile), 1, &(openfiles[fd].cache),true) < 0 ) { DEBUGF("Failed flushing cache\n"); @@ -250,12 +252,14 @@ static int readwrite(int fd, void* buf, int count, bool write) int rc = fat_readwrite(&(openfiles[fd].fatfile), 1, openfiles[fd].cache, true ); if ( rc < 0 ) { - DEBUGF("Failed read/writing\n"); errno = EIO; return -2; } + openfiles[fd].dirty = false; openfiles[fd].cacheoffset = -1; } + else + openfiles[fd].dirty = true; } else { memcpy( buf, openfiles[fd].cache + offs, headbytes ); @@ -265,6 +269,28 @@ static int readwrite(int fd, void* buf, int count, bool write) count -= headbytes; } + /* if buffer has been modified, write it back to disk */ + if (count && openfiles[fd].dirty) { + int rc; + DEBUGF("Flushing dirty sector cache\n"); + + /* seek back one sector to get file position right */ + rc = fat_seek(&(openfiles[fd].fatfile), + openfiles[fd].fileoffset / SECTOR_SIZE); + if ( rc < 0 ) { + errno = EIO; + return -3; + } + + rc = fat_readwrite(&(openfiles[fd].fatfile), 1, + openfiles[fd].cache, true ); + if ( rc < 0 ) { + errno = EIO; + return -4; + } + openfiles[fd].dirty = false; + } + /* read whole sectors right into the supplied buffer */ sectors = count / SECTOR_SIZE; if ( sectors ) { @@ -273,7 +299,7 @@ static int readwrite(int fd, void* buf, int count, bool write) if ( rc < 0 ) { DEBUGF("Failed read/writing %d sectors\n",sectors); errno = EIO; - return -3; + return -5; } else { if ( rc > 0 ) { @@ -305,7 +331,7 @@ static int readwrite(int fd, void* buf, int count, bool write) if ( rc < 0 ) { DEBUGF("Failed reading\n"); errno = EIO; - return -4; + return -6; } /* seek back one sector to put file position right */ rc = fat_seek(&(openfiles[fd].fatfile), @@ -314,17 +340,18 @@ static int readwrite(int fd, void* buf, int count, bool write) if ( rc < 0 ) { DEBUGF("fat_seek() failed\n"); errno = EIO; - return -5; + return -7; } } memcpy( openfiles[fd].cache, buf + nread, count ); + openfiles[fd].dirty = true; } else { if ( fat_readwrite(&(openfiles[fd].fatfile), 1, &(openfiles[fd].cache),false) < 1 ) { DEBUGF("Failed caching sector\n"); errno = EIO; - return -6; + return -8; } memcpy( buf + nread, openfiles[fd].cache, count ); } @@ -345,6 +372,10 @@ static int readwrite(int fd, void* buf, int count, bool write) int write(int fd, void* buf, int count) { + if (!openfiles[fd].write) { + errno = EACCES; + return -1; + } return readwrite(fd, buf, count, true); } @@ -369,13 +400,6 @@ int lseek(int fd, int offset, int whence) return -1; } - if ( openfiles[fd].write ) { - DEBUGF("lseek() is not supported when writing\n"); - errno = EROFS; - return -2; - } - - switch ( whence ) { case SEEK_SET: pos = offset; -- cgit v1.2.3