summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2010-01-01 20:41:29 +0000
committerAmaury Pouly <pamaury@rockbox.org>2010-01-01 20:41:29 +0000
commit839007872a4ae8d7fab58e877d9454a32540c08d (patch)
tree713d93157527f5a7ab932ac8d9cd0d6e7b31f207
parent2392bb41996963c6683253114bdfb3174146e7dc (diff)
downloadrockbox-839007872a4ae8d7fab58e877d9454a32540c08d.tar.gz
rockbox-839007872a4ae8d7fab58e877d9454a32540c08d.zip
FS#9409: fix rename which didn't close file handles on error and enventually cause cut/paste to fail between volumes.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24134 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/common/file.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c
index a80aed5396..7ec712a244 100644
--- a/firmware/common/file.c
+++ b/firmware/common/file.c
@@ -367,8 +367,10 @@ int rename(const char* path, const char* newpath)
367 nameptr = strrchr(newpath,'/'); 367 nameptr = strrchr(newpath,'/');
368 if (nameptr) 368 if (nameptr)
369 nameptr++; 369 nameptr++;
370 else 370 else {
371 close(fd);
371 return - 3; 372 return - 3;
373 }
372 374
373 /* Extract new path */ 375 /* Extract new path */
374 strcpy(newpath2, newpath); 376 strcpy(newpath2, newpath);
@@ -376,8 +378,10 @@ int rename(const char* path, const char* newpath)
376 dirptr = strrchr(newpath2,'/'); 378 dirptr = strrchr(newpath2,'/');
377 if(dirptr) 379 if(dirptr)
378 *dirptr = 0; 380 *dirptr = 0;
379 else 381 else {
382 close(fd);
380 return - 4; 383 return - 4;
384 }
381 385
382 dirptr = newpath2; 386 dirptr = newpath2;
383 387
@@ -386,8 +390,10 @@ int rename(const char* path, const char* newpath)
386 } 390 }
387 391
388 dir = opendir_uncached(dirptr); 392 dir = opendir_uncached(dirptr);
389 if(!dir) 393 if(!dir) {
394 close(fd);
390 return - 5; 395 return - 5;
396 }
391 397
392 file = &openfiles[fd]; 398 file = &openfiles[fd];
393 399
@@ -395,12 +401,16 @@ int rename(const char* path, const char* newpath)
395 file->size, file->attr); 401 file->size, file->attr);
396#ifdef HAVE_MULTIVOLUME 402#ifdef HAVE_MULTIVOLUME
397 if ( rc == -1) { 403 if ( rc == -1) {
404 close(fd);
405 closedir_uncached(dir);
398 DEBUGF("Failed renaming file across volumnes: %d\n", rc); 406 DEBUGF("Failed renaming file across volumnes: %d\n", rc);
399 errno = EXDEV; 407 errno = EXDEV;
400 return -6; 408 return -6;
401 } 409 }
402#endif 410#endif
403 if ( rc < 0 ) { 411 if ( rc < 0 ) {
412 close(fd);
413 closedir_uncached(dir);
404 DEBUGF("Failed renaming file: %d\n", rc); 414 DEBUGF("Failed renaming file: %d\n", rc);
405 errno = EIO; 415 errno = EIO;
406 return rc * 10 - 7; 416 return rc * 10 - 7;
@@ -412,6 +422,7 @@ int rename(const char* path, const char* newpath)
412 422
413 rc = close(fd); 423 rc = close(fd);
414 if (rc<0) { 424 if (rc<0) {
425 closedir_uncached(dir);
415 errno = EIO; 426 errno = EIO;
416 return rc * 10 - 8; 427 return rc * 10 - 8;
417 } 428 }