diff --git a/source/blender/blenlib/intern/fileops_c.cc b/source/blender/blenlib/intern/fileops_c.cc index 0046d1af75c..01e0467e75f 100644 --- a/source/blender/blenlib/intern/fileops_c.cc +++ b/source/blender/blenlib/intern/fileops_c.cc @@ -480,7 +480,18 @@ int BLI_rename(const char *from, const char *to) #elif defined(__GLIBC_PREREQ) # if __GLIBC_PREREQ(2, 28) /* Most common Linux cases. */ - return renameat2(AT_FDCWD, from, AT_FDCWD, to, RENAME_NOREPLACE); + int ret = renameat2(AT_FDCWD, from, AT_FDCWD, to, RENAME_NOREPLACE); + if (ret < 0 && errno == EINVAL) { + /* Most likely a filesystem that doesn't support RENAME_NOREPLACE. + * (For example NFS, Samba, exFAT, NTFS, etc) + * Retry with a non atomic operation. + */ + if (BLI_exists(to)) { + return 1; + } + return rename(from, to); + } + return ret; # endif #else /* At least all BSD's currently. */ diff --git a/source/blender/editors/space_file/file_draw.cc b/source/blender/editors/space_file/file_draw.cc index 752db114acc..ea3082a796d 100644 --- a/source/blender/editors/space_file/file_draw.cc +++ b/source/blender/editors/space_file/file_draw.cc @@ -821,26 +821,28 @@ static void renamebutton_cb(bContext *C, void * /*arg1*/, char *oldname) BLI_path_join(newname, sizeof(newname), params->dir, filename); if (!STREQ(orgname, newname)) { - if (!BLI_exists(newname)) { - errno = 0; - if ((BLI_rename(orgname, newname) != 0) || !BLI_exists(newname)) { - WM_reportf(RPT_ERROR, "Could not rename: %s", errno ? strerror(errno) : "unknown error"); - WM_report_banner_show(wm, win); - } - else { - /* If rename is successful, scroll to newly renamed entry. */ - STRNCPY(params->renamefile, filename); - file_params_invoke_rename_postscroll(wm, win, sfile); - } - - /* to make sure we show what is on disk */ - ED_fileselect_clear(wm, sfile); - } - else { + errno = 0; + if ((BLI_rename(orgname, newname) != 0) || !BLI_exists(newname)) { + WM_reportf(RPT_ERROR, "Could not rename: %s", errno ? strerror(errno) : "unknown error"); + WM_report_banner_show(wm, win); /* Renaming failed, reset the name for further renaming handling. */ STRNCPY(params->renamefile, oldname); } + else { + /* If rename is successful, set renamefile to newly renamed entry. + * This is used later to select and scroll to the file. + */ + STRNCPY(params->renamefile, filename); + } + /* Ensure we select and scroll to the renamed file. + * This is done even if the rename fails as we want to make sure that the file we tried to + * rename is still selected and in view. (it can move if something added files/folders to the + * directory while we were renaming. + */ + file_params_invoke_rename_postscroll(wm, win, sfile); + /* to make sure we show what is on disk */ + ED_fileselect_clear(wm, sfile); ED_region_tag_redraw(region); } }