summaryrefslogtreecommitdiff
path: root/zen/file_access.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zen/file_access.cpp')
-rw-r--r--zen/file_access.cpp31
1 files changed, 14 insertions, 17 deletions
diff --git a/zen/file_access.cpp b/zen/file_access.cpp
index 09a1eb07..84d3b264 100644
--- a/zen/file_access.cpp
+++ b/zen/file_access.cpp
@@ -434,26 +434,29 @@ void renameFile_sub(const Zstring& pathSource, const Zstring& pathTarget) //thro
if (lastError == ERROR_NOT_SAME_DEVICE)
throw ErrorDifferentVolume(errorMsg, errorDescr);
- else if (lastError == ERROR_ALREADY_EXISTS || //-> used on Win7 x64
+ if (lastError == ERROR_ALREADY_EXISTS || //-> used on Win7 x64
lastError == ERROR_FILE_EXISTS) //-> used by XP???
throw ErrorTargetExisting(errorMsg, errorDescr);
- else
- throw FileError(errorMsg, errorDescr);
+ throw FileError(errorMsg, errorDescr);
}
#elif defined ZEN_LINUX || defined ZEN_MAC
- if (::rename(pathSource.c_str(), pathTarget.c_str()) != 0)
+ //rename() will never fail with EEXIST, but always overwrite!
+ //=> OS X: no solution
+ //=> Linux: renameat2() with RENAME_NOREPLACE -> still new, probably buggy
+ const bool alreadyExists = somethingExists(pathTarget); //we have to let go of atomicity!
+
+ if (alreadyExists || ::rename(pathSource.c_str(), pathTarget.c_str()) != 0)
{
- const int lastError = errno; //copy before directly or indirectly making other system calls!
+ const int lastError = alreadyExists ? EEXIST : errno; //copy before directly or indirectly making other system calls!
const std::wstring errorMsg = replaceCpy(replaceCpy(_("Cannot move file %x to %y."), L"%x", L"\n" + fmtPath(pathSource)), L"%y", L"\n" + fmtPath(pathTarget));
const std::wstring errorDescr = formatSystemError(L"rename", lastError);
if (lastError == EXDEV)
throw ErrorDifferentVolume(errorMsg, errorDescr);
- else if (lastError == EEXIST)
- throw ErrorTargetExisting(errorMsg, errorDescr);
- else
- throw FileError(errorMsg, errorDescr);
+ if (lastError == EEXIST)
+ throw ErrorTargetExisting(errorMsg, errorDescr);
+ throw FileError(errorMsg, errorDescr);
}
#endif
}
@@ -2039,12 +2042,6 @@ DWORD CALLBACK copyCallbackInternal(LARGE_INTEGER totalFileSize,
return PROGRESS_CONTINUE;
}
-#if defined _MSC_VER && _MSC_VER > 1800
- #error get rid!
-#endif
-const bool supportNonEncryptedDestination = winXpOrLater(); //encrypted destination is not supported with Windows 2000
-//caveat: function scope static initialization is not thread-safe in VS 2010! -> still not sufficient if multiple threads access during static init!!!
-
InSyncAttributes copyFileWindowsDefault(const Zstring& sourceFile, //throw FileError, ErrorTargetExisting, ErrorFileLocked, ErrorFallbackToCopyAsBackupStream
const Zstring& targetFile,
@@ -2062,8 +2059,8 @@ InSyncAttributes copyFileWindowsDefault(const Zstring& sourceFile, //throw FileE
DWORD copyFlags = COPY_FILE_FAIL_IF_EXISTS;
- if (supportNonEncryptedDestination)
- copyFlags |= COPY_FILE_ALLOW_DECRYPTED_DESTINATION; //allow copying from encrypted to non-encrypted location
+ //encrypted destination is not supported with Windows 2000! -> whatever
+ copyFlags |= COPY_FILE_ALLOW_DECRYPTED_DESTINATION; //allow copying from encrypted to non-encrypted location
//if (vistaOrLater()) //see http://blogs.technet.com/b/askperf/archive/2007/05/08/slow-large-file-copy-issues.aspx
// copyFlags |= COPY_FILE_NO_BUFFERING; //no perf difference at worst, improvement for large files (20% in test NTFS -> NTFS)
bgstack15