diff options
author | B Stack <bgstack15@gmail.com> | 2020-09-01 00:24:17 +0000 |
---|---|---|
committer | B Stack <bgstack15@gmail.com> | 2020-09-01 00:24:17 +0000 |
commit | 5a3f52b016581a6a0cb4513614b6c620d365dde2 (patch) | |
tree | acfdfb3e1046db87040477033fda0df76d92916a /zen/file_access.cpp | |
parent | Merge branch '11.0' into 'master' (diff) | |
parent | add upstream 11.1 (diff) | |
download | FreeFileSync-11.1.tar.gz FreeFileSync-11.1.tar.bz2 FreeFileSync-11.1.zip |
Merge branch '11.1' into 'master'11.1
add upstream 11.1
See merge request opensource-tracking/FreeFileSync!25
Diffstat (limited to 'zen/file_access.cpp')
-rw-r--r-- | zen/file_access.cpp | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/zen/file_access.cpp b/zen/file_access.cpp index 10713ce5..7d3fbfc5 100644 --- a/zen/file_access.cpp +++ b/zen/file_access.cpp @@ -84,7 +84,7 @@ std::optional<Zstring> zen::getParentFolderPath(const Zstring& itemPath) if (comp->relPath.empty()) return {}; - const Zstring parentRelPath = beforeLast(comp->relPath, FILE_NAME_SEPARATOR, IF_MISSING_RETURN_NONE); + const Zstring parentRelPath = beforeLast(comp->relPath, FILE_NAME_SEPARATOR, IfNotFoundReturn::none); if (parentRelPath.empty()) return comp->rootPath; return appendSeparator(comp->rootPath) + parentRelPath; @@ -123,7 +123,7 @@ std::optional<ItemType> zen::itemStillExists(const Zstring& itemPath) //throw Fi // ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND, ERROR_INVALID_NAME, ERROR_INVALID_DRIVE, // ERROR_NOT_READY, ERROR_INVALID_PARAMETER, ERROR_BAD_PATHNAME, ERROR_BAD_NETPATH => not reliable - const Zstring itemName = afterLast(itemPath, FILE_NAME_SEPARATOR, IF_MISSING_RETURN_ALL); + const Zstring itemName = afterLast(itemPath, FILE_NAME_SEPARATOR, IfNotFoundReturn::all); assert(!itemName.empty()); const std::optional<ItemType> parentType = itemStillExists(*parentPath); //throw FileError @@ -316,8 +316,11 @@ void moveAndRenameFileSub(const Zstring& pathFrom, const Zstring& pathTo, bool r if (ec == EXDEV) throw ErrorMoveUnsupported(errorMsg, errorDescr); - if (ec == EEXIST) + + assert(!replaceExisting || ec != EEXIST); + if (!replaceExisting && ec == EEXIST) throw ErrorTargetExisting(errorMsg, errorDescr); + throw FileError(errorMsg, errorDescr); }; @@ -518,16 +521,16 @@ void zen::createDirectory(const Zstring& dirPath) //throw FileError, ErrorTarget auto getErrorMsg = [&] { return replaceCpy(_("Cannot create directory %x."), L"%x", fmtPath(dirPath)); }; //don't allow creating irregular folders like "...." https://social.technet.microsoft.com/Forums/windows/en-US/ffee2322-bb6b-4fdf-86f9-8f93cf1fa6cb/ - const Zstring dirName = afterLast(dirPath, FILE_NAME_SEPARATOR, IF_MISSING_RETURN_ALL); + const Zstring dirName = afterLast(dirPath, FILE_NAME_SEPARATOR, IfNotFoundReturn::all); if (std::all_of(dirName.begin(), dirName.end(), [](Zchar c) { return c == Zstr('.'); })) /**/throw FileError(getErrorMsg(), replaceCpy<std::wstring>(L"Invalid folder name %x.", L"%x", fmtPath(dirName))); - #if 0 //not appreciated: https://freefilesync.org/forum/viewtopic.php?t=7509 +#if 0 //not appreciated: https://freefilesync.org/forum/viewtopic.php?t=7509 //not critical, but will visually confuse user sooner or later: if (startsWith(dirName, Zstr(' ')) || endsWith (dirName, Zstr(' '))) throw FileError(getErrorMsg(), replaceCpy<std::wstring>(L"Folder name %x starts/ends with space character.", L"%x", fmtPath(dirName))); - #endif +#endif const mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; //0777, default for newly created directories @@ -638,14 +641,10 @@ FileCopyResult zen::copyNewFile(const Zstring& sourceFile, const Zstring& target throw FileError(errorMsg, errorDescr); } - ZEN_ON_SCOPE_FAIL( try { removeFilePlain(targetFile); } - catch (FileError&) {} ); - //place guard AFTER ::open() and BEFORE lifetime of FileOutput: - //=> don't delete file that existed previously!!! FileOutput fileOut(fdTarget, targetFile, IOCallbackDivider(notifyUnbufferedIO, totalUnbufferedIO)); //pass ownership - //fileOut.preAllocateSpaceBestEffort(sourceInfo.st_size); //throw FileError - //=> perf: seems like no real benefit... + //preallocate disk space + reduce fragmentation (perf: no real benefit) + fileOut.reserveSpace(sourceInfo.st_size); //throw FileError bufferedStreamCopy(fileIn, fileOut); //throw FileError, (ErrorFileLocked), X @@ -659,6 +658,10 @@ FileCopyResult zen::copyNewFile(const Zstring& sourceFile, const Zstring& target //close output file handle before setting file time; also good place to catch errors when closing stream! fileOut.finalize(); //throw FileError, (X) essentially a close() since buffers were already flushed + //========================================================================================================== + //take fileOut ownership => from this point on, WE are responsible for calling removeFilePlain() on failure!! + //=========================================================================================================== + std::optional<FileError> errorModTime; try { |