forked from len0rd/rockbox
Added support for O_RDWR and lseek() while writing.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2826 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
1e524abd5b
commit
228605dc7b
1 changed files with 38 additions and 14 deletions
|
@ -38,11 +38,12 @@
|
||||||
struct filedesc {
|
struct filedesc {
|
||||||
unsigned char cache[SECTOR_SIZE];
|
unsigned char cache[SECTOR_SIZE];
|
||||||
int cacheoffset;
|
int cacheoffset;
|
||||||
unsigned int fileoffset;
|
int fileoffset;
|
||||||
int size;
|
int size;
|
||||||
struct fat_file fatfile;
|
struct fat_file fatfile;
|
||||||
bool busy;
|
bool busy;
|
||||||
bool write;
|
bool write;
|
||||||
|
bool dirty;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct filedesc openfiles[MAX_OPEN_FILES];
|
static struct filedesc openfiles[MAX_OPEN_FILES];
|
||||||
|
@ -85,6 +86,7 @@ int open(const char* pathname, int flags)
|
||||||
openfiles[fd].write = false;
|
openfiles[fd].write = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case O_RDWR:
|
||||||
case O_WRONLY:
|
case O_WRONLY:
|
||||||
openfiles[fd].write = true;
|
openfiles[fd].write = true;
|
||||||
break;
|
break;
|
||||||
|
@ -168,7 +170,7 @@ int close(int fd)
|
||||||
}
|
}
|
||||||
if (openfiles[fd].write) {
|
if (openfiles[fd].write) {
|
||||||
/* flush sector cache */
|
/* flush sector cache */
|
||||||
if ( openfiles[fd].cacheoffset != -1 ) {
|
if ( openfiles[fd].dirty ) {
|
||||||
if ( fat_readwrite(&(openfiles[fd].fatfile), 1,
|
if ( fat_readwrite(&(openfiles[fd].fatfile), 1,
|
||||||
&(openfiles[fd].cache),true) < 0 ) {
|
&(openfiles[fd].cache),true) < 0 ) {
|
||||||
DEBUGF("Failed flushing cache\n");
|
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,
|
int rc = fat_readwrite(&(openfiles[fd].fatfile), 1,
|
||||||
openfiles[fd].cache, true );
|
openfiles[fd].cache, true );
|
||||||
if ( rc < 0 ) {
|
if ( rc < 0 ) {
|
||||||
DEBUGF("Failed read/writing\n");
|
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
openfiles[fd].dirty = false;
|
||||||
openfiles[fd].cacheoffset = -1;
|
openfiles[fd].cacheoffset = -1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
openfiles[fd].dirty = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memcpy( buf, openfiles[fd].cache + offs, headbytes );
|
memcpy( buf, openfiles[fd].cache + offs, headbytes );
|
||||||
|
@ -265,6 +269,28 @@ static int readwrite(int fd, void* buf, int count, bool write)
|
||||||
count -= headbytes;
|
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 */
|
/* read whole sectors right into the supplied buffer */
|
||||||
sectors = count / SECTOR_SIZE;
|
sectors = count / SECTOR_SIZE;
|
||||||
if ( sectors ) {
|
if ( sectors ) {
|
||||||
|
@ -273,7 +299,7 @@ static int readwrite(int fd, void* buf, int count, bool write)
|
||||||
if ( rc < 0 ) {
|
if ( rc < 0 ) {
|
||||||
DEBUGF("Failed read/writing %d sectors\n",sectors);
|
DEBUGF("Failed read/writing %d sectors\n",sectors);
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -3;
|
return -5;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( rc > 0 ) {
|
if ( rc > 0 ) {
|
||||||
|
@ -305,7 +331,7 @@ static int readwrite(int fd, void* buf, int count, bool write)
|
||||||
if ( rc < 0 ) {
|
if ( rc < 0 ) {
|
||||||
DEBUGF("Failed reading\n");
|
DEBUGF("Failed reading\n");
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -4;
|
return -6;
|
||||||
}
|
}
|
||||||
/* seek back one sector to put file position right */
|
/* seek back one sector to put file position right */
|
||||||
rc = fat_seek(&(openfiles[fd].fatfile),
|
rc = fat_seek(&(openfiles[fd].fatfile),
|
||||||
|
@ -314,17 +340,18 @@ static int readwrite(int fd, void* buf, int count, bool write)
|
||||||
if ( rc < 0 ) {
|
if ( rc < 0 ) {
|
||||||
DEBUGF("fat_seek() failed\n");
|
DEBUGF("fat_seek() failed\n");
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -5;
|
return -7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memcpy( openfiles[fd].cache, buf + nread, count );
|
memcpy( openfiles[fd].cache, buf + nread, count );
|
||||||
|
openfiles[fd].dirty = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( fat_readwrite(&(openfiles[fd].fatfile), 1,
|
if ( fat_readwrite(&(openfiles[fd].fatfile), 1,
|
||||||
&(openfiles[fd].cache),false) < 1 ) {
|
&(openfiles[fd].cache),false) < 1 ) {
|
||||||
DEBUGF("Failed caching sector\n");
|
DEBUGF("Failed caching sector\n");
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -6;
|
return -8;
|
||||||
}
|
}
|
||||||
memcpy( buf + nread, openfiles[fd].cache, count );
|
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)
|
int write(int fd, void* buf, int count)
|
||||||
{
|
{
|
||||||
|
if (!openfiles[fd].write) {
|
||||||
|
errno = EACCES;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return readwrite(fd, buf, count, true);
|
return readwrite(fd, buf, count, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,13 +400,6 @@ int lseek(int fd, int offset, int whence)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( openfiles[fd].write ) {
|
|
||||||
DEBUGF("lseek() is not supported when writing\n");
|
|
||||||
errno = EROFS;
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
switch ( whence ) {
|
switch ( whence ) {
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
pos = offset;
|
pos = offset;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue