From 1f4669fa4c1517cc1018dc53c52662046296dff0 Mon Sep 17 00:00:00 2001 From: Aly Cerruti Date: Fri, 16 Apr 2021 14:01:40 -0700 Subject: [PATCH] Support replacing files in `rename` for better compatibility with POSIX (#483) --- libctru/source/archive_dev.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/libctru/source/archive_dev.c b/libctru/source/archive_dev.c index 59c8d7b37..50a1d6a62 100644 --- a/libctru/source/archive_dev.c +++ b/libctru/source/archive_dev.c @@ -980,12 +980,29 @@ archive_rename(struct _reent *r, } rc = FSUSER_RenameFile(sourceDevice->archive, fs_path_old, sourceDevice->archive, fs_path_new); - if(R_SUCCEEDED(rc)) - return 0; + /* if the file at the target destination exists, overwrite it */ + if(R_FAILED(rc) && R_DESCRIPTION(rc) == RD_ALREADY_EXISTS) { + rc = FSUSER_DeleteFile(sourceDevice->archive, fs_path_new); + if(R_FAILED(rc)) { + r->_errno = archive_translate_error(rc); + return -1; + } + rc = FSUSER_RenameFile(sourceDevice->archive, fs_path_old, sourceDevice->archive, fs_path_new); + if(R_SUCCEEDED(rc)) return 0; + } else if(R_SUCCEEDED(rc)) return 0; rc = FSUSER_RenameDirectory(sourceDevice->archive, fs_path_old, sourceDevice->archive, fs_path_new); - if(R_SUCCEEDED(rc)) - return 0; + /* if the directory at the target destination exists, overwrite it */ + if(R_FAILED(rc) && R_DESCRIPTION(rc) == RD_ALREADY_EXISTS) { + /* only overwrite empty directories */ + rc = FSUSER_DeleteDirectory(sourceDevice-> archive, fs_path_new); + if(R_FAILED(rc)) { + r->_errno = archive_translate_error(rc); + return -1; + } + rc = FSUSER_RenameDirectory(sourceDevice->archive, fs_path_old, sourceDevice->archive, fs_path_new); + if(R_SUCCEEDED(rc)) return 0; + } else if(R_SUCCEEDED(rc)) return 0; r->_errno = archive_translate_error(rc); return -1;