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
This commit is contained in:
Linus Nielsen Feltzing 2004-08-22 11:28:24 +00:00
parent 1a6a4812aa
commit e0e0140f4e
3 changed files with 44 additions and 12 deletions

View file

@ -277,12 +277,16 @@ int remove(const char* name)
int rename(const char* path, const char* newpath) int rename(const char* path, const char* newpath)
{ {
int rc, fd; int rc, fd;
DIR* dir;
char* nameptr; char* nameptr;
char* dirptr;
struct filedesc* file; struct filedesc* file;
char newpath2[MAX_PATH];
/* verify new path does not already exist */ /* verify new path does not already exist */
/* If it is a directory, errno == EISDIR if the name exists */
fd = open(newpath, O_RDONLY); fd = open(newpath, O_RDONLY);
if ( fd >= 0 ) { if ( fd >= 0 || errno == EISDIR) {
close(fd); close(fd);
errno = EBUSY; errno = EBUSY;
return -1; return -1;
@ -295,25 +299,51 @@ int rename(const char* path, const char* newpath)
return fd * 10 - 2; return fd * 10 - 2;
} }
/* strip path */ /* extract new file name */
nameptr = strrchr(newpath,'/'); nameptr = strrchr(newpath,'/');
if (nameptr) if (nameptr)
nameptr++; nameptr++;
else 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]; 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 ) { if ( rc < 0 ) {
DEBUGF("Failed renaming file: %d\n", rc); DEBUGF("Failed renaming file: %d\n", rc);
errno = EIO; errno = EIO;
return rc * 10 - 3; return rc * 10 - 6;
} }
rc = close(fd); rc = close(fd);
if (rc<0) { if (rc<0) {
errno = EIO; errno = EIO;
return rc * 10 - 4; return rc * 10 - 7;
}
rc = closedir(dir);
if (rc<0) {
errno = EIO;
return rc * 10 - 8;
} }
return 0; return 0;

View file

@ -1551,12 +1551,13 @@ int fat_remove(struct fat_file* file)
} }
int fat_rename(struct fat_file* file, int fat_rename(struct fat_file* file,
struct fat_dir* dir,
const unsigned char* newname, const unsigned char* newname,
int size, int size,
int attr) int attr)
{ {
int rc; int rc;
struct fat_dir dir; struct fat_dir olddir;
struct fat_file newfile = *file; struct fat_file newfile = *file;
if ( !file->dircluster ) { if ( !file->dircluster ) {
@ -1565,12 +1566,12 @@ int fat_rename(struct fat_file* file,
} }
/* create a temporary file handle */ /* create a temporary file handle */
rc = fat_opendir(&dir, file->dircluster, NULL); rc = fat_opendir(&olddir, file->dircluster, NULL);
if (rc < 0) if (rc < 0)
return rc * 10 - 2; return rc * 10 - 2;
/* create new name */ /* create new name */
rc = add_dir_entry(&dir, &newfile, newname, false, false); rc = add_dir_entry(dir, &newfile, newname, false, false);
if (rc < 0) if (rc < 0)
return rc * 10 - 3; return rc * 10 - 3;

View file

@ -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_remove(struct fat_file *ent);
extern int fat_truncate(const struct fat_file *ent); extern int fat_truncate(const struct fat_file *ent);
extern int fat_rename(struct fat_file* file, extern int fat_rename(struct fat_file* file,
struct fat_dir* dir,
const unsigned char* newname, const unsigned char* newname,
int size, int attr); int size, int attr);