From 4ebdd283c5434e7d3d284b91be7e396e857a4562 Mon Sep 17 00:00:00 2001 From: Aly Date: Thu, 15 Apr 2021 14:07:22 -0700 Subject: [PATCH 1/3] Support replacing files in `rename` for better compatibility with POSIX --- libctru/source/archive_dev.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/libctru/source/archive_dev.c b/libctru/source/archive_dev.c index 59c8d7b37..6ac50f89e 100644 --- a/libctru/source/archive_dev.c +++ b/libctru/source/archive_dev.c @@ -980,12 +980,23 @@ 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(rc == 0xC82044BE) { + rc = FSUSER_DeleteFile(sourceDevice->archive, fs_path_new); + if(R_FAILED(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(rc == 0xC82044BE) { + /* only overwrite empty directories */ + rc = FSUSER_DeleteDirectory(sourceDevice-> archive, fs_path_new); + if(R_FAILED(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; From d6417f82cc6b80a06b68d16eafdcbeb0102590da Mon Sep 17 00:00:00 2001 From: Aly Date: Fri, 16 Apr 2021 12:19:14 -0700 Subject: [PATCH 2/3] Don't use magic numbers in error checks --- libctru/source/archive_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libctru/source/archive_dev.c b/libctru/source/archive_dev.c index 6ac50f89e..cea0c0a10 100644 --- a/libctru/source/archive_dev.c +++ b/libctru/source/archive_dev.c @@ -981,7 +981,7 @@ archive_rename(struct _reent *r, rc = FSUSER_RenameFile(sourceDevice->archive, fs_path_old, sourceDevice->archive, fs_path_new); /* if the file at the target destination exists, overwrite it */ - if(rc == 0xC82044BE) { + if(R_FAILED(rc) && R_DESCRIPTION(rc) == RD_ALREADY_EXISTS) { rc = FSUSER_DeleteFile(sourceDevice->archive, fs_path_new); if(R_FAILED(rc)) return -1; rc = FSUSER_RenameFile(sourceDevice->archive, fs_path_old, sourceDevice->archive, fs_path_new); @@ -990,7 +990,7 @@ archive_rename(struct _reent *r, rc = FSUSER_RenameDirectory(sourceDevice->archive, fs_path_old, sourceDevice->archive, fs_path_new); /* if the directory at the target destination exists, overwrite it */ - if(rc == 0xC82044BE) { + 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)) return -1; From 36b6bb19317219005695fb939fcecf5b69f4f8de Mon Sep 17 00:00:00 2001 From: Aly Date: Fri, 16 Apr 2021 12:21:45 -0700 Subject: [PATCH 3/3] Set errno on failure to delete files --- libctru/source/archive_dev.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libctru/source/archive_dev.c b/libctru/source/archive_dev.c index cea0c0a10..50a1d6a62 100644 --- a/libctru/source/archive_dev.c +++ b/libctru/source/archive_dev.c @@ -983,7 +983,10 @@ archive_rename(struct _reent *r, /* 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)) return -1; + 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; @@ -993,7 +996,10 @@ archive_rename(struct _reent *r, 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)) return -1; + 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;