summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-11-11 10:21:51 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-11-11 10:21:51 +0000
commit11a09e632ceb5513aad54aa6b2c6031bb28b4533 (patch)
treee0f1a0d93d40dbeab2c0e20fa240880e5ad67d0c
parent7912a6d39d73a73022feee41ba5fce8ee3ae6019 (diff)
close() now does not truncate the file.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2821 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/common/file.c42
-rw-r--r--firmware/drivers/fat.c36
-rw-r--r--firmware/drivers/fat.h3
3 files changed, 57 insertions, 24 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c
index 1dd71d98ae..b2c2644725 100644
--- a/firmware/common/file.c
+++ b/firmware/common/file.c
@@ -38,7 +38,7 @@
struct filedesc {
unsigned char cache[SECTOR_SIZE];
int cacheoffset;
- int fileoffset;
+ unsigned int fileoffset;
int size;
struct fat_file fatfile;
bool busy;
@@ -178,7 +178,7 @@ int close(int fd)
}
/* tie up all loose ends */
- fat_closewrite(&(openfiles[fd].fatfile), openfiles[fd].fileoffset);
+ fat_closewrite(&(openfiles[fd].fatfile), openfiles[fd].size);
}
openfiles[fd].busy = false;
return rc;
@@ -191,7 +191,21 @@ int remove(const char* name)
if ( fd < 0 )
return fd;
+ rc = fat_truncate(&(openfiles[fd].fatfile));
+ if ( rc < 0 ) {
+ DEBUGF("Failed truncating file\n");
+ errno = EIO;
+ return -1;
+ }
+
rc = fat_remove(&(openfiles[fd].fatfile));
+ if ( rc < 0 ) {
+ DEBUGF("Failed removing file\n");
+ errno = EIO;
+ return -2;
+ }
+
+ openfiles[fd].size = 0;
close(fd);
@@ -259,7 +273,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 -2;
+ return -3;
}
else {
if ( rc > 0 ) {
@@ -278,10 +292,30 @@ static int readwrite(int fd, void* buf, int count, bool write)
openfiles[fd].cacheoffset = -1;
}
}
+ openfiles[fd].fileoffset += nread;
+ nread = 0;
/* any tail bytes? */
if ( count ) {
if (write) {
+ /* sector is only partially filled. copy-back from disk */
+ int rc;
+ LDEBUGF("Copy-back tail cache\n");
+ rc = fat_readwrite(&(openfiles[fd].fatfile), 1,
+ openfiles[fd].cache, false );
+ if ( rc < 0 ) {
+ DEBUGF("Failed reading\n");
+ errno = EIO;
+ return -4;
+ }
+ /* seek back one sector to put file position right */
+ rc = fat_seek(&(openfiles[fd].fatfile),
+ openfiles[fd].fileoffset / SECTOR_SIZE);
+ if ( rc < 0 ) {
+ DEBUGF("fat_seek() failed\n");
+ errno = EIO;
+ return -5;
+ }
memcpy( openfiles[fd].cache, buf + nread, count );
}
else {
@@ -289,7 +323,7 @@ static int readwrite(int fd, void* buf, int count, bool write)
&(openfiles[fd].cache),false) < 1 ) {
DEBUGF("Failed caching sector\n");
errno = EIO;
- return -1;
+ return -6;
}
memcpy( buf + nread, openfiles[fd].cache, count );
}
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index 47bfd1afef..74bdbd3491 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -167,7 +167,7 @@ static unsigned int getcurrdostime(unsigned short *dosdate,
unsigned short *dostime,
unsigned char *dostenth);
static int create_dos_name(unsigned char *name, unsigned char *newname);
-static int find_free_cluster(int start);
+static unsigned int find_free_cluster(unsigned int start);
#endif
#define FAT_CACHE_SIZE 0x20
@@ -438,10 +438,10 @@ static void *cache_fat_sector(int fatsector)
return sectorbuf;
}
-static int find_free_cluster(int startcluster)
+static unsigned int find_free_cluster(unsigned int startcluster)
{
- int sector = startcluster / CLUSTERS_PER_FAT_SECTOR;
- int offset = startcluster % CLUSTERS_PER_FAT_SECTOR;
+ unsigned int sector = startcluster / CLUSTERS_PER_FAT_SECTOR;
+ unsigned int offset = startcluster % CLUSTERS_PER_FAT_SECTOR;
int i;
/* don't waste time scanning if the disk is already full */
@@ -511,7 +511,7 @@ static int update_fat_entry(unsigned int entry, unsigned int val)
return 0;
}
-static int read_fat_entry(int entry)
+static int read_fat_entry(unsigned int entry)
{
int sector = entry / CLUSTERS_PER_FAT_SECTOR;
int offset = entry % CLUSTERS_PER_FAT_SECTOR;
@@ -998,24 +998,23 @@ int fat_create_file(char* name,
return err;
}
-int fat_closewrite(struct fat_file *file, int size)
+int fat_truncate(struct fat_file *file)
{
- int next, last = file->lastcluster;
- int endcluster = last;
-
- LDEBUGF("fat_closewrite(size=%d, last=%x)\n",size, last);
-
/* truncate trailing clusters */
- last = get_next_cluster(last);
+ int next;
+ int last = get_next_cluster(file->lastcluster);
while ( last && last != FAT_EOF_MARK ) {
next = get_next_cluster(last);
update_fat_entry(last,0);
last = next;
}
- /* if no cluster was written, size is 0 */
- if (!endcluster)
- size = 0;
+ return 0;
+}
+
+int fat_closewrite(struct fat_file *file, int size)
+{
+ LDEBUGF("fat_closewrite(size=%d)\n",size);
if (!size) {
/* empty file */
@@ -1024,18 +1023,17 @@ int fat_closewrite(struct fat_file *file, int size)
file->firstcluster = 0;
}
}
- else
- update_fat_entry(endcluster, FAT_EOF_MARK);
if (file->dirsector)
update_dir_entry(file, size);
flush_fat();
#ifdef TEST_FAT
- {
+ if ( file->firstcluster ) {
/* debug */
int count = 0;
int len;
+ int next;
for ( next = file->firstcluster; next;
next = get_next_cluster(next) )
LDEBUGF("cluster %d: %x\n", count++, next);
@@ -1213,7 +1211,7 @@ int fat_readwrite( struct fat_file *file, int sectorcount,
return i;
}
-int fat_seek(struct fat_file *file, int seeksector )
+int fat_seek(struct fat_file *file, unsigned int seeksector )
{
int clusternum=0, sectornum=0, sector=0;
int cluster = file->firstcluster;
diff --git a/firmware/drivers/fat.h b/firmware/drivers/fat.h
index 6ed68ad8d8..b23d8dfa08 100644
--- a/firmware/drivers/fat.h
+++ b/firmware/drivers/fat.h
@@ -79,8 +79,9 @@ extern int fat_create_file(char* name,
extern int fat_readwrite(struct fat_file *ent, int sectorcount,
void* buf, bool write );
extern int fat_closewrite(struct fat_file *ent, int size);
-extern int fat_seek(struct fat_file *ent, int sector );
+extern int fat_seek(struct fat_file *ent, unsigned int sector );
extern int fat_remove(struct fat_file *ent);
+extern int fat_truncate(struct fat_file *ent);
extern int fat_opendir(struct fat_dir *ent, unsigned int currdir);
extern int fat_getnext(struct fat_dir *ent, struct fat_direntry *entry);