diff options
author | Amaury Pouly <pamaury@rockbox.org> | 2010-01-01 20:41:29 +0000 |
---|---|---|
committer | Amaury Pouly <pamaury@rockbox.org> | 2010-01-01 20:41:29 +0000 |
commit | 839007872a4ae8d7fab58e877d9454a32540c08d (patch) | |
tree | 713d93157527f5a7ab932ac8d9cd0d6e7b31f207 | |
parent | 2392bb41996963c6683253114bdfb3174146e7dc (diff) | |
download | rockbox-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.c | 17 |
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 | } |