diff options
author | B. Stack <bgstack15@gmail.com> | 2023-06-20 07:46:53 -0400 |
---|---|---|
committer | B. Stack <bgstack15@gmail.com> | 2023-06-20 07:46:53 -0400 |
commit | f76994f1fb3e25c4563c9d8afce6bbc86701d1d2 (patch) | |
tree | b39389163603195a0169af57712eb0765e5c11f4 /zen | |
parent | add upstream 12.3 (diff) | |
download | FreeFileSync-f76994f1fb3e25c4563c9d8afce6bbc86701d1d2.tar.gz FreeFileSync-f76994f1fb3e25c4563c9d8afce6bbc86701d1d2.tar.bz2 FreeFileSync-f76994f1fb3e25c4563c9d8afce6bbc86701d1d2.zip |
add upstream 12.412.4
Diffstat (limited to 'zen')
-rw-r--r-- | zen/file_access.cpp | 12 | ||||
-rw-r--r-- | zen/file_io.cpp | 6 | ||||
-rw-r--r-- | zen/file_path.cpp | 1 | ||||
-rw-r--r-- | zen/json.h | 2 | ||||
-rw-r--r-- | zen/legacy_compiler.h | 6 | ||||
-rw-r--r-- | zen/perf.h | 30 | ||||
-rw-r--r-- | zen/scope_guard.h | 2 | ||||
-rw-r--r-- | zen/serialize.h | 16 | ||||
-rw-r--r-- | zen/symlink_target.h | 14 | ||||
-rw-r--r-- | zen/sys_info.cpp | 12 | ||||
-rw-r--r-- | zen/sys_info.h | 4 | ||||
-rw-r--r-- | zen/utf.h | 2 |
12 files changed, 65 insertions, 42 deletions
diff --git a/zen/file_access.cpp b/zen/file_access.cpp index 24e418c9..6c47936c 100644 --- a/zen/file_access.cpp +++ b/zen/file_access.cpp @@ -64,7 +64,7 @@ std::variant<ItemType, Zstring /*last existing parent path*/> getItemTypeIfExist } catch (const SysErrorCode& e) //let's dig deeper, but *only* if error code sounds like "not existing" { - const std::optional<Zstring> parentPath = getParentFolderPath(itemPath); + const std::optional<Zstring>& parentPath = getParentFolderPath(itemPath); if (!parentPath) //device root => quick access test throw; if (e.errorCode == ENOENT) @@ -178,8 +178,6 @@ uint64_t zen::getFileSize(const Zstring& filePath) //throw FileError } - - Zstring zen::getTempFolderPath() //throw FileError { if (const std::optional<Zstring> tempDirPath = getEnvironmentVar("TMPDIR")) @@ -561,7 +559,7 @@ void zen::createDirectoryIfMissingRecursion(const Zstring& dirPath) //throw File } catch (FileError&) //not yet existing or access error { - const std::optional<Zstring> parentPath = getParentFolderPath(dirPathEx); + const std::optional<Zstring>& parentPath = getParentFolderPath(dirPathEx); if (!parentPath)//device root => quick access test throw; dirNames.push_front(getItemName(dirPathEx)); @@ -667,7 +665,7 @@ FileCopyResult zen::copyNewFile(const Zstring& sourceFile, const Zstring& target } FileOutputPlain fileOut(fdTarget, targetFile); //pass ownership - //preallocate disk space + reduce fragmentation (perf: no real benefit) + //preallocate disk space + reduce fragmentation fileOut.reserveSpace(sourceInfo.st_size); //throw FileError unbufferedStreamCopy([&](void* buffer, size_t bytesToRead) @@ -686,8 +684,10 @@ FileCopyResult zen::copyNewFile(const Zstring& sourceFile, const Zstring& target }, fileOut.getBlockSize() /*throw FileError*/); //throw FileError, X + //possible improvement: copy_file_range() performs an in-kernel copy: https://github.com/coreutils/coreutils/blob/17479ef60c8edbd2fe8664e31a7f69704f0cd221/src/copy.c#L342 + #if 0 - //clean file system cache: needed at all? no user complaints at all!!! + //clean file system cache: needed at all? no user complaints at all so far!!! //posix_fadvise(POSIX_FADV_DONTNEED) does nothing, unless data was already read from/written to disk: https://insights.oetiker.ch/linux/fadvise/ // => should be "most" of the data at this point => good enough? if (::posix_fadvise(fileIn.getHandle(), 0 /*offset*/, 0 /*len*/, POSIX_FADV_DONTNEED) != 0) //"len == 0" means "end of the file" diff --git a/zen/file_io.cpp b/zen/file_io.cpp index 2e4ab60a..8c985f64 100644 --- a/zen/file_io.cpp +++ b/zen/file_io.cpp @@ -245,6 +245,11 @@ void FileOutputPlain::reserveSpace(uint64_t expectedSize) //throw FileError try { +#if 0 /* fallocate(FALLOC_FL_KEEP_SIZE): + - perf: no real benefit (in a quick and dirty local test) + - breaks Btrfs compression: https://freefilesync.org/forum/viewtopic.php?t=10356 + - apparently not even used by cp: https://github.com/coreutils/coreutils/blob/17479ef60c8edbd2fe8664e31a7f69704f0cd221/src/copy.c#LL1234C5-L1234C5 */ + //don't use ::posix_fallocate which uses horribly inefficient fallback if FS doesn't support it (EOPNOTSUPP) and changes files size! //FALLOC_FL_KEEP_SIZE => allocate only, file size is NOT changed! if (::fallocate(getHandle(), //int fd @@ -253,6 +258,7 @@ void FileOutputPlain::reserveSpace(uint64_t expectedSize) //throw FileError expectedSize) != 0) //off_t len if (errno != EOPNOTSUPP) //possible, unlike with posix_fallocate() THROW_LAST_SYS_ERROR("fallocate"); +#endif } catch (const SysError& e) { throw FileError(replaceCpy(_("Cannot write file %x."), L"%x", fmtPath(getFilePath())), e.toString()); } diff --git a/zen/file_path.cpp b/zen/file_path.cpp index c9d6f236..60ac4eb7 100644 --- a/zen/file_path.cpp +++ b/zen/file_path.cpp @@ -5,6 +5,7 @@ // ***************************************************************************** #include "file_path.h" +#include "thread.h" using namespace zen; @@ -333,7 +333,7 @@ public: Scanner(const std::string& stream) : stream_(stream), pos_(stream_.begin()) { if (zen::startsWith(stream_, BYTE_ORDER_MARK_UTF8)) - pos_ += strLength(BYTE_ORDER_MARK_UTF8); + pos_ += BYTE_ORDER_MARK_UTF8.size(); } Token getNextToken() //throw JsonParsingError diff --git a/zen/legacy_compiler.h b/zen/legacy_compiler.h index 8606f95c..2070d60f 100644 --- a/zen/legacy_compiler.h +++ b/zen/legacy_compiler.h @@ -20,7 +20,8 @@ GCC https://gcc.gnu.org/projects/cxx-status.html libstdc++ https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html - Clang https://clang.llvm.org/cxx_status.html#cxx20 + Clang https://clang.llvm.org/cxx_status.html + Xcode https://developer.apple.com/xcode/cpp libc++ https://libcxx.llvm.org/cxx2a_status.html */ @@ -39,6 +40,9 @@ basic_string<Char, Traits, Alloc> operator+(basic_string<Char, Traits, Alloc>&& } //--------------------------------------------------------------------------------- +//support for std::string::resize_and_overwrite() +#define ZEN_HAVE_RESIZE_AND_OVERWRITE 1 + namespace zen { double fromChars(const char* first, const char* last); @@ -40,45 +40,35 @@ namespace zen class StopWatch { public: - explicit StopWatch(bool startPaused = false) : paused_(startPaused) {} + explicit StopWatch(bool startPaused = false) + { + if (startPaused) + startTime_ = {}; + } - bool isPaused() const { return paused_; } + bool isPaused() const { return startTime_ == std::chrono::steady_clock::time_point{}; } void pause() { - if (!paused_) - { - paused_ = true; - elapsedUntilPause_ += std::chrono::steady_clock::now() - startTime_; - } + if (!isPaused()) + elapsedUntilPause_ += std::chrono::steady_clock::now() - std::exchange(startTime_, {}); } void resume() { - if (paused_) - { - paused_ = false; + if (isPaused()) startTime_ = std::chrono::steady_clock::now(); - } - } - - void restart() - { - paused_ = false; - startTime_ = std::chrono::steady_clock::now(); - elapsedUntilPause_ = std::chrono::nanoseconds::zero(); } std::chrono::nanoseconds elapsed() const { auto elapsedTotal = elapsedUntilPause_; - if (!paused_) + if (!isPaused()) elapsedTotal += std::chrono::steady_clock::now() - startTime_; return elapsedTotal; } private: - bool paused_; std::chrono::steady_clock::time_point startTime_ = std::chrono::steady_clock::now(); std::chrono::nanoseconds elapsedUntilPause_{}; //std::chrono::duration is uninitialized by default! WTF! When will this stupidity end! }; diff --git a/zen/scope_guard.h b/zen/scope_guard.h index 4cc049a8..9b27eecb 100644 --- a/zen/scope_guard.h +++ b/zen/scope_guard.h @@ -23,7 +23,7 @@ namespace zen Scope Exit: ZEN_ON_SCOPE_EXIT (CleanUp()); - ZEN_ON_SCOPE_FAIL (UndoPreviousWork()); + ZEN_ON_SCOPE_FAIL (UndoTemporaryWork()); ZEN_ON_SCOPE_SUCCESS(NotifySuccess()); */ enum class ScopeGuardRunMode diff --git a/zen/serialize.h b/zen/serialize.h index 8ccecd53..02dcd2b2 100644 --- a/zen/serialize.h +++ b/zen/serialize.h @@ -261,11 +261,21 @@ BinContainer unbufferedLoad(Function tryRead /*(void* buffer, size_t bytesToRead BinContainer buf; for (;;) { - warn_static("don't need zero-initialization!") - buf.resize(buf.size() + blockSize); +#ifndef ZEN_HAVE_RESIZE_AND_OVERWRITE +#error include legacy_compiler.h! +#endif +#if ZEN_HAVE_RESIZE_AND_OVERWRITE //permature(?) perf optimization; avoid needless zero-initialization: + size_t bytesRead = 0; + buf.resize_and_overwrite(buf.size() + blockSize, [&, bufSizeOld = buf.size()](char* rawBuf, size_t /*rawBufSize: caveat: may be larger than what's requested*/) + { + bytesRead = tryRead(rawBuf + bufSizeOld, blockSize); //throw X; may return short; only 0 means EOF + return bufSizeOld + bytesRead; + }); +#else + buf.resize(buf.size() + blockSize); //needless zero-initialization! const size_t bytesRead = tryRead(buf.data() + buf.size() - blockSize, blockSize); //throw X; may return short; only 0 means EOF buf.resize(buf.size() - blockSize + bytesRead); //caveat: unsigned arithmetics - +#endif if (bytesRead == 0) //end of file { //caveat: memory consumption of returned string! diff --git a/zen/symlink_target.h b/zen/symlink_target.h index 083360af..8580a9dd 100644 --- a/zen/symlink_target.h +++ b/zen/symlink_target.h @@ -8,6 +8,7 @@ #define SYMLINK_TARGET_H_801783470198357483 #include "file_error.h" +#include "file_path.h" #include <unistd.h> #include <stdlib.h> //realpath @@ -35,12 +36,14 @@ Zstring getSymlinkResolvedPath(const Zstring& linkPath); //throw FileError //################################ implementation ################################ + +namespace zen +{ namespace { //retrieve raw target data of symlink or junction -zen::SymlinkRawContent getSymlinkRawContent_impl(const Zstring& linkPath) //throw SysError +SymlinkRawContent getSymlinkRawContent_impl(const Zstring& linkPath) //throw SysError { - using namespace zen; const size_t bufSize = 10000; std::vector<char> buf(bufSize); @@ -54,9 +57,8 @@ zen::SymlinkRawContent getSymlinkRawContent_impl(const Zstring& linkPath) //thro } -Zstring getResolvedSymlinkPath_impl(const Zstring& linkPath) //throw SysError +Zstring getSymlinkResolvedPath_impl(const Zstring& linkPath) //throw SysError { - using namespace zen; char* targetPath = ::realpath(linkPath.c_str(), nullptr); if (!targetPath) THROW_LAST_SYS_ERROR("realpath"); @@ -66,8 +68,6 @@ Zstring getResolvedSymlinkPath_impl(const Zstring& linkPath) //throw SysError } -namespace zen -{ inline SymlinkRawContent getSymlinkRawContent(const Zstring& linkPath) { @@ -84,7 +84,7 @@ Zstring getSymlinkResolvedPath(const Zstring& linkPath) { try { - return getResolvedSymlinkPath_impl(linkPath); //throw SysError + return getSymlinkResolvedPath_impl(linkPath); //throw SysError } catch (const SysError& e) { throw FileError(replaceCpy(_("Cannot determine final path for %x."), L"%x", fmtPath(linkPath)), e.toString()); } } diff --git a/zen/sys_info.cpp b/zen/sys_info.cpp index 2a32d247..c3680ec7 100644 --- a/zen/sys_info.cpp +++ b/zen/sys_info.cpp @@ -207,7 +207,7 @@ std::wstring zen::getOsDescription() //throw FileError -Zstring zen::getRealProcessPath() //throw FileError +Zstring zen::getProcessPath() //throw FileError { try { @@ -284,3 +284,13 @@ Zstring zen::getUserDownloadsPath() //throw FileError } catch (const SysError& e) { throw FileError(_("Cannot get process information."), e.toString()); } } + + +bool zen::runningElevated() //throw FileError +{ + if (::geteuid() != 0) //nofail; non-root + return false; + + return getLoginUser() != "root"; //throw FileError + //consider "root login" like "UAC disabled" on Windows +} diff --git a/zen/sys_info.h b/zen/sys_info.h index ce07d7a1..ed5dc1d6 100644 --- a/zen/sys_info.h +++ b/zen/sys_info.h @@ -30,12 +30,14 @@ ComputerModel getComputerModel(); //throw FileError std::wstring getOsDescription(); //throw FileError -Zstring getRealProcessPath(); //throw FileError +Zstring getProcessPath(); //throw FileError Zstring getUserDownloadsPath(); //throw FileError Zstring getUserDataPath(); //throw FileError Zstring getUserHome(); //throw FileError + +bool runningElevated(); //throw FileError } #endif //SYSTEM_H_4189731847832147508915 @@ -16,7 +16,7 @@ namespace zen template <class TargetString, class SourceString> TargetString utfTo(const SourceString& str); -const std::string_view BYTE_ORDER_MARK_UTF8 = "\xEF\xBB\xBF"; +constexpr std::string_view BYTE_ORDER_MARK_UTF8 = "\xEF\xBB\xBF"; template <class UtfString> bool isValidUtf(const UtfString& str); //check for UTF-8 encoding errors |