diff options
author | B Stack <bgstack15@gmail.com> | 2020-07-22 11:37:03 -0400 |
---|---|---|
committer | B Stack <bgstack15@gmail.com> | 2020-07-22 11:37:03 -0400 |
commit | c95b3937fef3e2c63768f1b3b1dc2c898f23d91d (patch) | |
tree | 10260e25ae905564f7978b83fc4e316670f987c6 /zen/file_access.cpp | |
parent | Merge branch '10.25' into 'master' (diff) | |
download | FreeFileSync-c95b3937fef3e2c63768f1b3b1dc2c898f23d91d.tar.gz FreeFileSync-c95b3937fef3e2c63768f1b3b1dc2c898f23d91d.tar.bz2 FreeFileSync-c95b3937fef3e2c63768f1b3b1dc2c898f23d91d.zip |
add upstream 11.0
Diffstat (limited to 'zen/file_access.cpp')
-rw-r--r-- | zen/file_access.cpp | 80 |
1 files changed, 28 insertions, 52 deletions
diff --git a/zen/file_access.cpp b/zen/file_access.cpp index 8f021843..10713ce5 100644 --- a/zen/file_access.cpp +++ b/zen/file_access.cpp @@ -176,7 +176,7 @@ int64_t zen::getFreeDiskSpace(const Zstring& path) //throw FileError, returns < struct ::statfs info = {}; if (::statfs(path.c_str(), &info) != 0) THROW_LAST_FILE_ERROR(replaceCpy(_("Cannot determine free disk space for %x."), L"%x", fmtPath(path)), "statfs"); - + return static_cast<int64_t>(info.f_bsize) * info.f_bavail; } @@ -205,11 +205,12 @@ Zstring zen::getTempFolderPath() //throw FileError { if (const char* buf = ::getenv("TMPDIR")) //no extended error reporting return buf; - + //TMPDIR not set on CentOS 7, WTF! return P_tmpdir; //usually resolves to "/tmp" } + void zen::removeFilePlain(const Zstring& filePath) //throw FileError { const char* functionName = "unlink"; @@ -300,11 +301,11 @@ namespace /* Usage overview: (avoid circular pattern!) - moveAndRenameItem() --> moveAndRenameFileSub() - | /|\ - \|/ | - Fix8Dot3NameClash() -*/ + moveAndRenameItem() --> moveAndRenameFileSub() + | /|\ + \|/ | + Fix8Dot3NameClash() */ + //wrapper for file system rename function: void moveAndRenameFileSub(const Zstring& pathFrom, const Zstring& pathTo, bool replaceExisting) //throw FileError, ErrorMoveUnsupported, ErrorTargetExisting { @@ -521,10 +522,12 @@ void zen::createDirectory(const Zstring& dirPath) //throw FileError, ErrorTarget 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 //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 const mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; //0777, default for newly created directories @@ -542,16 +545,16 @@ void zen::createDirectory(const Zstring& dirPath) //throw FileError, ErrorTarget } -void zen::createDirectoryIfMissingRecursion(const Zstring& dirPath) //throw FileError +bool zen::createDirectoryIfMissingRecursion(const Zstring& dirPath) //throw FileError { const std::optional<Zstring> parentPath = getParentFolderPath(dirPath); if (!parentPath) //device root - return; + return false; try //generally we expect that path already exists (see: ffs_paths.cpp) => check first { if (getItemType(dirPath) != ItemType::file) //throw FileError - return; + return false; } catch (FileError&) {} //not yet existing or access error? let's find out... @@ -560,13 +563,14 @@ void zen::createDirectoryIfMissingRecursion(const Zstring& dirPath) //throw File try { createDirectory(dirPath); //throw FileError, ErrorTargetExisting + return true; } catch (FileError&) { try { if (getItemType(dirPath) != ItemType::file) //throw FileError - return; //already existing => possible, if createDirectoryIfMissingRecursion() is run in parallel + return true; //already existing => possible, if createDirectoryIfMissingRecursion() is run in parallel } catch (FileError&) {} //not yet existing or access error @@ -580,12 +584,19 @@ void zen::tryCopyDirectoryAttributes(const Zstring& sourcePath, const Zstring& t } -void zen::copySymlink(const Zstring& sourcePath, const Zstring& targetPath, bool copyFilePermissions) //throw FileError +void zen::copySymlink(const Zstring& sourcePath, const Zstring& targetPath) //throw FileError { - const Zstring linkPath = getSymlinkTargetRaw(sourcePath); //throw FileError; accept broken symlinks + const SymlinkRawContent linkContent = getSymlinkRawContent(sourcePath); //throw FileError; accept broken symlinks - if (::symlink(linkPath.c_str(), targetPath.c_str()) != 0) - THROW_LAST_FILE_ERROR(replaceCpy(replaceCpy(_("Cannot copy symbolic link %x to %y."), L"%x", L'\n' + fmtPath(sourcePath)), L"%y", L'\n' + fmtPath(targetPath)), "symlink"); + try //harmonize with NativeFileSystem::equalSymlinkContentForSameAfsType() + { + if (::symlink(linkContent.targetPath.c_str(), targetPath.c_str()) != 0) + THROW_LAST_SYS_ERROR("symlink"); + } + catch (const SysError& e) + { + throw FileError(replaceCpy(replaceCpy(_("Cannot copy symbolic link %x to %y."), L"%x", L'\n' + fmtPath(sourcePath)), L"%y", L'\n' + fmtPath(targetPath)), e.toString()); + } //allow only consistent objects to be created -> don't place before ::symlink(); targetPath may already exist! ZEN_ON_SCOPE_FAIL(try { removeSymlinkPlain(targetPath); /*throw FileError*/ } @@ -597,17 +608,11 @@ void zen::copySymlink(const Zstring& sourcePath, const Zstring& targetPath, bool THROW_LAST_FILE_ERROR(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtPath(sourcePath)), "lstat"); setWriteTimeNative(targetPath, sourceInfo.st_mtim, ProcSymlink::DIRECT); //throw FileError - - if (copyFilePermissions) - copyItemPermissions(sourcePath, targetPath, ProcSymlink::DIRECT); //throw FileError } -namespace -{ -FileCopyResult copyFileOsSpecific(const Zstring& sourceFile, //throw FileError, ErrorTargetExisting - const Zstring& targetFile, - const IOCallback& notifyUnbufferedIO) +FileCopyResult zen::copyNewFile(const Zstring& sourceFile, const Zstring& targetFile, //throw FileError, ErrorTargetExisting, (ErrorFileLocked), X + const IOCallback& notifyUnbufferedIO /*throw X*/) { int64_t totalUnbufferedIO = 0; @@ -678,33 +683,4 @@ FileCopyResult copyFileOsSpecific(const Zstring& sourceFile, //throw FileError, return result; } -/* ------------------ - |File Copy Layers| - ------------------ - copyNewFile - | - copyFileOsSpecific (solve 8.3 issue on Windows) - | - copyFileWindowsSelectRoutine - / \ -copyFileWindowsDefault(::CopyFileEx) copyFileWindowsStream(::BackupRead/::BackupWrite) -*/ -} - - -FileCopyResult zen::copyNewFile(const Zstring& sourceFile, const Zstring& targetFile, bool copyFilePermissions, //throw FileError, ErrorTargetExisting, ErrorFileLocked, X - const IOCallback& notifyUnbufferedIO /*throw X*/) -{ - const FileCopyResult result = copyFileOsSpecific(sourceFile, targetFile, notifyUnbufferedIO); //throw FileError, ErrorTargetExisting, ErrorFileLocked, X - - //at this point we know we created a new file, so it's fine to delete it for cleanup! - ZEN_ON_SCOPE_FAIL(try { removeFilePlain(targetFile); } - catch (FileError&) {}); - - if (copyFilePermissions) - copyItemPermissions(sourceFile, targetFile, ProcSymlink::FOLLOW); //throw FileError - - return result; -} - |