summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2004-08-22 11:28:24 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2004-08-22 11:28:24 +0000
commite0e0140f4e63b451a110840dc5ef5c22c3ed9f7c (patch)
tree6e48d6ddc4609f9a49eb2913b145b8d1f81e5436
parent1a6a4812aa46d66ca46e308897e0cf759e42773f (diff)
downloadrockbox-e0e0140f4e63b451a110840dc5ef5c22c3ed9f7c.zip
rockbox-e0e0140f4e63b451a110840dc5ef5c22c3ed9f7c.tar.gz
rockbox-e0e0140f4e63b451a110840dc5ef5c22c3ed9f7c.tar.bz2
rockbox-e0e0140f4e63b451a110840dc5ef5c22c3ed9f7c.tar.xz
Bug fix: renaming a directory could cause a name clash. New feature: rename() can now move files/directories as well.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5008 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/common/file.c42
-rw-r--r--firmware/drivers/fat.c13
-rw-r--r--firmware/export/fat.h1
3 files changed, 44 insertions, 12 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c
index e875d43..546a927 100644
--- a/firmware/common/file.c
+++ b/firmware/common/file.c
@@ -277,12 +277,16 @@ int remove(const char* name)
int rename(const char* path, const char* newpath)
{
int rc, fd;
+ DIR* dir;
char* nameptr;
+ char* dirptr;
struct filedesc* file;
+ char newpath2[MAX_PATH];
/* verify new path does not already exist */
+ /* If it is a directory, errno == EISDIR if the name exists */
fd = open(newpath, O_RDONLY);
- if ( fd >= 0 ) {
+ if ( fd >= 0 || errno == EISDIR) {
close(fd);
errno = EBUSY;
return -1;
@@ -295,25 +299,51 @@ int rename(const char* path, const char* newpath)
return fd * 10 - 2;
}
- /* strip path */
+ /* extract new file name */
nameptr = strrchr(newpath,'/');
if (nameptr)
nameptr++;
else
- nameptr = (char*)newpath;
+ return - 3;
+
+ /* Extract new path */
+ strcpy(newpath2, newpath);
+
+ dirptr = strrchr(newpath2,'/');
+ if(dirptr)
+ *dirptr = 0;
+ else
+ return - 4;
+ dirptr = newpath2;
+
+ if(strlen(dirptr) == 0) {
+ dirptr = "/";
+ }
+
+ dir = opendir(dirptr);
+ if(!dir)
+ return - 5;
+
file = &openfiles[fd];
- rc = fat_rename(&file->fatfile, nameptr, file->size, file->attr);
+ rc = fat_rename(&file->fatfile, &dir->fatdir, nameptr,
+ file->size, file->attr);
if ( rc < 0 ) {
DEBUGF("Failed renaming file: %d\n", rc);
errno = EIO;
- return rc * 10 - 3;
+ return rc * 10 - 6;
}
rc = close(fd);
if (rc<0) {
errno = EIO;
- return rc * 10 - 4;
+ return rc * 10 - 7;
+ }
+
+ rc = closedir(dir);
+ if (rc<0) {
+ errno = EIO;
+ return rc * 10 - 8;
}
return 0;
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index 1b53015..e41bbac 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -1551,12 +1551,13 @@ int fat_remove(struct fat_file* file)
}
int fat_rename(struct fat_file* file,
- const unsigned char* newname,
- int size,
- int attr)
+ struct fat_dir* dir,
+ const unsigned char* newname,
+ int size,
+ int attr)
{
int rc;
- struct fat_dir dir;
+ struct fat_dir olddir;
struct fat_file newfile = *file;
if ( !file->dircluster ) {
@@ -1565,12 +1566,12 @@ int fat_rename(struct fat_file* file,
}
/* create a temporary file handle */
- rc = fat_opendir(&dir, file->dircluster, NULL);
+ rc = fat_opendir(&olddir, file->dircluster, NULL);
if (rc < 0)
return rc * 10 - 2;
/* create new name */
- rc = add_dir_entry(&dir, &newfile, newname, false, false);
+ rc = add_dir_entry(dir, &newfile, newname, false, false);
if (rc < 0)
return rc * 10 - 3;
diff --git a/firmware/export/fat.h b/firmware/export/fat.h
index f4f09a2..6f9c9c5 100644
--- a/firmware/export/fat.h
+++ b/firmware/export/fat.h
@@ -89,6 +89,7 @@ extern int fat_seek(struct fat_file *ent, unsigned int sector );
extern int fat_remove(struct fat_file *ent);
extern int fat_truncate(const struct fat_file *ent);
extern int fat_rename(struct fat_file* file,
+ struct fat_dir* dir,
const unsigned char* newname,
int size, int attr);