summaryrefslogtreecommitdiff
path: root/zen
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2016-03-16 21:32:07 +0100
committerDaniel Wilhelm <daniel@wili.li>2016-03-16 21:32:07 +0100
commitce3574cf7ff2ee68608b4d001f5a6dd1e36b2252 (patch)
tree576b1741351e1cd34f0fcce49f98df9c17e10912 /zen
parent7.6 (diff)
downloadFreeFileSync-ce3574cf7ff2ee68608b4d001f5a6dd1e36b2252.tar.gz
FreeFileSync-ce3574cf7ff2ee68608b4d001f5a6dd1e36b2252.tar.bz2
FreeFileSync-ce3574cf7ff2ee68608b4d001f5a6dd1e36b2252.zip
7.7
Diffstat (limited to 'zen')
-rw-r--r--zen/basic_math.h6
-rw-r--r--zen/file_access.cpp35
-rw-r--r--zen/file_io.cpp18
-rw-r--r--zen/format_unit.cpp8
-rw-r--r--zen/i18n.h6
-rw-r--r--zen/scope_guard.h7
-rw-r--r--zen/thread.h36
-rw-r--r--zen/type_traits.h9
8 files changed, 71 insertions, 54 deletions
diff --git a/zen/basic_math.h b/zen/basic_math.h
index 8b745caf..a15d811a 100644
--- a/zen/basic_math.h
+++ b/zen/basic_math.h
@@ -38,7 +38,7 @@ template <class T>
T clampCpy(const T& val, const T& minVal, const T& maxVal);
template <class T, class InputIterator> //precondition: range must be sorted!
-auto nearMatch(const T& val, InputIterator first, InputIterator last) -> typename std::iterator_traits<InputIterator>::value_type;
+auto nearMatch(const T& val, InputIterator first, InputIterator last);
template <class T>
bool isNull(T value);
@@ -195,10 +195,10 @@ std::pair<InputIterator, InputIterator> minMaxElement(InputIterator first, Input
*/
template <class T, class InputIterator> inline
-auto nearMatch(const T& val, InputIterator first, InputIterator last) -> typename std::iterator_traits<InputIterator>::value_type
+auto nearMatch(const T& val, InputIterator first, InputIterator last)
{
if (first == last)
- return 0;
+ return static_cast<decltype(*first)>(0);
assert(std::is_sorted(first, last));
InputIterator it = std::lower_bound(first, last, val);
diff --git a/zen/file_access.cpp b/zen/file_access.cpp
index 2ca373aa..a66cbc6b 100644
--- a/zen/file_access.cpp
+++ b/zen/file_access.cpp
@@ -828,7 +828,7 @@ void setFileTimeRaw(const Zstring& filePath,
throw FileError(errorMsg, formatSystemError(L"SetFileTime", ec));
}
}
-#ifndef NDEBUG //verify written data: mainly required to check consistency of DST hack
+#ifndef NDEBUG //verify written data
FILETIME creationTimeDbg = {};
FILETIME lastWriteTimeDbg = {};
@@ -1347,9 +1347,9 @@ void zen::copyNewDirectory(const Zstring& sourcePath, const Zstring& targetPath,
bool copyFilePermissions)
{
#ifdef ZEN_WIN
-auto getErrorMsg = [](const Zstring& path){ return replaceCpy(_("Cannot create directory %x."), L"%x", fmtPath(path)); };
+ auto getErrorMsg = [](const Zstring& path) { return replaceCpy(_("Cannot create directory %x."), L"%x", fmtPath(path)); };
-//special handling for volume root: trying to create existing root directory results in ERROR_ACCESS_DENIED rather than ERROR_ALREADY_EXISTS!
+ //special handling for volume root: trying to create existing root directory results in ERROR_ACCESS_DENIED rather than ERROR_ALREADY_EXISTS!
Zstring dirTmp = removeLongPathPrefix(endsWith(targetPath, FILE_NAME_SEPARATOR) ?
beforeLast(targetPath, FILE_NAME_SEPARATOR, IF_MISSING_RETURN_NONE) :
targetPath);
@@ -1359,7 +1359,7 @@ auto getErrorMsg = [](const Zstring& path){ return replaceCpy(_("Cannot create d
dirTmp += FILE_NAME_SEPARATOR; //we do not support "C:" to represent a relative path!
const DWORD ec = somethingExists(dirTmp) ? ERROR_ALREADY_EXISTS : ERROR_PATH_NOT_FOUND; //don't use dirExists() => harmonize with ErrorTargetExisting!
- const std::wstring errorDescr = formatSystemError(L"CreateDirectory", ec);
+ const std::wstring errorDescr = formatSystemError(L"CreateDirectory", ec);
if (ec == ERROR_ALREADY_EXISTS)
throw ErrorTargetExisting(getErrorMsg(dirTmp), errorDescr);
@@ -1412,7 +1412,7 @@ auto getErrorMsg = [](const Zstring& path){ return replaceCpy(_("Cannot create d
if (!sourcePath.empty())
if (::stat(sourcePath.c_str(), &dirInfo) == 0)
{
- mode = dirInfo.st_mode; //analog to "cp" which copies "mode" (considering umask) by default
+ mode = dirInfo.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); //analog to "cp" which copies "mode" (considering umask) by default
mode |= S_IRWXU; //FFS only: we need full access to copy child items! "cp" seems to apply permissions *after* copying child items
}
//=> need copyItemPermissions() only for "chown" and umask-agnostic permissions
@@ -1783,8 +1783,8 @@ InSyncAttributes copyFileWindowsBackupStream(const Zstring& sourceFile, //throw
//create targetFile and open it for writing
HANDLE hFileTarget = ::CreateFile(applyLongPathPrefix(targetFile).c_str(), //_In_ LPCTSTR lpFileName,
- GENERIC_READ | GENERIC_WRITE, //_In_ DWORD dwDesiredAccess,
- //read access required for FSCTL_SET_COMPRESSION
+ GENERIC_READ | GENERIC_WRITE | DELETE, //_In_ DWORD dwDesiredAccess,
+ //GENERIC_READ required for FSCTL_SET_COMPRESSION, DELETE for ::SetFileInformationByHandle(),FileDispositionInfo
FILE_SHARE_DELETE, //_In_ DWORD dwShareMode,
//FILE_SHARE_DELETE is required to rename file while handle is open!
nullptr, //_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
@@ -1808,10 +1808,27 @@ InSyncAttributes copyFileWindowsBackupStream(const Zstring& sourceFile, //throw
throw FileError(errorMsg, errorDescr);
}
+#ifndef ZEN_WIN_VISTA_AND_LATER
ZEN_ON_SCOPE_FAIL(try { removeFile(targetFile); }
- catch (FileError&) {} ); //transactional behavior: guard just after opening target and before managing hFileTarget
+ catch (FileError&) {} ); //transactional behavior: guard just after opening target and before managing hFileTarget
+#endif
+
ZEN_ON_SCOPE_EXIT(::CloseHandle(hFileTarget));
+#ifdef ZEN_WIN_VISTA_AND_LATER
+ //no need for ::DeleteFile(), we already have an open handle! Maybe this also prevents needless buffer-flushing in ::CloseHandle()??? Anyway, same behavior like ::CopyFileEx()
+ ZEN_ON_SCOPE_FAIL
+ (
+ FILE_DISPOSITION_INFO di = {};
+ di.DeleteFile = true;
+ if (!::SetFileInformationByHandle(hFileTarget, //_In_ HANDLE hFile,
+ FileDispositionInfo, //_In_ FILE_INFO_BY_HANDLE_CLASS FileInformationClass,
+ &di, //_In_ LPVOID lpFileInformation,
+ sizeof(di))) //_In_ DWORD dwBufferSize
+ assert(false);
+ );
+#endif
+
//----------------------------------------------------------------------
BY_HANDLE_FILE_INFORMATION fileInfoTarget = {};
if (!::GetFileInformationByHandle(hFileTarget, &fileInfoTarget))
@@ -1820,7 +1837,7 @@ InSyncAttributes copyFileWindowsBackupStream(const Zstring& sourceFile, //throw
//return up-to-date file attributes
InSyncAttributes newAttrib;
newAttrib.fileSize = get64BitUInt(fileInfoSource.nFileSizeLow, fileInfoSource.nFileSizeHigh);
- newAttrib.modificationTime = filetimeToTimeT(fileInfoSource.ftLastWriteTime); //no DST hack (yet)
+ newAttrib.modificationTime = filetimeToTimeT(fileInfoSource.ftLastWriteTime);
newAttrib.sourceFileId = extractFileId(fileInfoSource);
newAttrib.targetFileId = extractFileId(fileInfoTarget);
diff --git a/zen/file_io.cpp b/zen/file_io.cpp
index 5e8b7a1d..b385ce33 100644
--- a/zen/file_io.cpp
+++ b/zen/file_io.cpp
@@ -79,11 +79,11 @@ FileInput::FileInput(const Zstring& filepath) : //throw FileError, ErrorFileLock
auto createHandle = [&](DWORD dwShareMode)
{
return ::CreateFile(applyLongPathPrefix(filepath).c_str(), //_In_ LPCTSTR lpFileName,
- GENERIC_READ, //_In_ DWORD dwDesiredAccess,
- dwShareMode, //_In_ DWORD dwShareMode,
- nullptr, //_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- OPEN_EXISTING, //_In_ DWORD dwCreationDisposition,
- FILE_FLAG_SEQUENTIAL_SCAN //_In_ DWORD dwFlagsAndAttributes,
+ GENERIC_READ, //_In_ DWORD dwDesiredAccess,
+ dwShareMode, //_In_ DWORD dwShareMode,
+ nullptr, //_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ OPEN_EXISTING, //_In_ DWORD dwCreationDisposition,
+ FILE_FLAG_SEQUENTIAL_SCAN | //_In_ DWORD dwFlagsAndAttributes,
/* possible values: (Reference http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx#caching_behavior)
FILE_FLAG_NO_BUFFERING
FILE_FLAG_RANDOM_ACCESS
@@ -108,7 +108,7 @@ FileInput::FileInput(const Zstring& filepath) : //throw FileError, ErrorFileLock
for FFS most comparisons are probably between different disks => let's use FILE_FLAG_SEQUENTIAL_SCAN
*/
- | FILE_FLAG_BACKUP_SEMANTICS,
+ FILE_FLAG_BACKUP_SEMANTICS,
nullptr); //_In_opt_ HANDLE hTemplateFile
};
fileHandle = createHandle(FILE_SHARE_READ | FILE_SHARE_DELETE);
@@ -249,8 +249,8 @@ FileOutput::FileOutput(const Zstring& filepath, AccessFlag access) : //throw Fil
nullptr, //_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
dwCreationDisposition, //_In_ DWORD dwCreationDisposition,
dwFlagsAndAttributes |
- FILE_FLAG_SEQUENTIAL_SCAN //_In_ DWORD dwFlagsAndAttributes,
- | FILE_FLAG_BACKUP_SEMANTICS,
+ FILE_FLAG_SEQUENTIAL_SCAN | //_In_ DWORD dwFlagsAndAttributes,
+ FILE_FLAG_BACKUP_SEMANTICS,
nullptr); //_In_opt_ HANDLE hTemplateFile
};
@@ -298,7 +298,7 @@ FileOutput::FileOutput(const Zstring& filepath, AccessFlag access) : //throw Fil
//checkForUnsupportedType(filepath); -> not needed, open() + O_WRONLY should fail fast
fileHandle = ::open(filepath.c_str(), O_WRONLY | O_CREAT | (access == FileOutput::ACC_CREATE_NEW ? O_EXCL : O_TRUNC),
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); //0666
if (fileHandle == -1)
{
const int ec = errno; //copy before making other system calls!
diff --git a/zen/format_unit.cpp b/zen/format_unit.cpp
index e9c686aa..cfaaa329 100644
--- a/zen/format_unit.cpp
+++ b/zen/format_unit.cpp
@@ -194,7 +194,7 @@ class IntegerFormat
{
public:
static const NUMBERFMT& get() { return getInst().fmt; }
- static bool isValid() { return getInst().valid_; }
+ static bool isValid() { return getInst().valid; }
private:
static const IntegerFormat& getInst()
@@ -202,7 +202,7 @@ private:
#if defined _MSC_VER && _MSC_VER < 1900
#error function scope static initialization is not yet thread-safe!
#endif
- static IntegerFormat inst;
+ static const IntegerFormat inst;
return inst;
}
@@ -229,14 +229,14 @@ private:
else
grouping += L'0';
fmt.Grouping = stringTo<UINT>(grouping);
- valid_ = true;
+ valid = true;
}
}
NUMBERFMT fmt = {};
std::wstring thousandSep;
std::wstring decimalSep;
- bool valid_ = false;
+ bool valid = false;
};
}
#endif
diff --git a/zen/i18n.h b/zen/i18n.h
index 3ab5748a..e58542c2 100644
--- a/zen/i18n.h
+++ b/zen/i18n.h
@@ -99,7 +99,7 @@ std::wstring translate(const std::wstring& singular, const std::wstring& plural,
inline
-std::unique_ptr<const TranslationHandler>& globalHandler()
+std::unique_ptr<const TranslationHandler>& globalTranslationHandler()
{
static std::unique_ptr<const TranslationHandler> inst; //external linkage even in header!
return inst;
@@ -108,11 +108,11 @@ std::unique_ptr<const TranslationHandler>& globalHandler()
inline
-void setTranslator(std::unique_ptr<const TranslationHandler>&& newHandler) { implementation::globalHandler() = std::move(newHandler); }
+void setTranslator(std::unique_ptr<const TranslationHandler>&& newHandler) { implementation::globalTranslationHandler() = std::move(newHandler); }
inline
-const TranslationHandler* getTranslator() { return implementation::globalHandler().get(); }
+const TranslationHandler* getTranslator() { return implementation::globalTranslationHandler().get(); }
}
#endif //I18_N_H_3843489325044253425456
diff --git a/zen/scope_guard.h b/zen/scope_guard.h
index 791764de..1345447e 100644
--- a/zen/scope_guard.h
+++ b/zen/scope_guard.h
@@ -73,11 +73,11 @@ public:
~ScopeGuard() noexcept(runMode != ScopeGuardRunMode::ON_SUCCESS)
{
+ if (!dismissed)
+ {
#ifdef _MSC_VER
#pragma warning(suppress: 4127) //"conditional expression is constant"
#endif
- if (!dismissed)
- {
if (runMode != ScopeGuardRunMode::ON_EXIT)
{
const bool failed = getUncaughtExceptionCount() > exeptionCount;
@@ -85,6 +85,9 @@ public:
return;
}
+#ifdef _MSC_VER
+ #pragma warning(suppress: 4127) //"conditional expression is constant"
+#endif
if (runMode == ScopeGuardRunMode::ON_SUCCESS)
fun_(); //throw X
else
diff --git a/zen/thread.h b/zen/thread.h
index bb6e7901..700d42dc 100644
--- a/zen/thread.h
+++ b/zen/thread.h
@@ -13,7 +13,7 @@
#include "type_traits.h"
#include "optional.h"
#ifdef ZEN_WIN
-#include "win.h"
+ #include "win.h"
#endif
@@ -63,7 +63,7 @@ template <class Rep, class Period>
void interruptibleSleep(const std::chrono::duration<Rep, Period>& relTime); //throw ThreadInterruption
#ifdef ZEN_WIN
-void setCurrentThreadName(const char* threadName);
+ void setCurrentThreadName(const char* threadName);
#endif
//------------------------------------------------------------------------------------------
@@ -421,10 +421,10 @@ void InterruptibleThread::interrupt() { intStatus_->interrupt(); }
#pragma pack(push,8)
struct THREADNAME_INFO
{
- DWORD dwType; // Must be 0x1000.
- LPCSTR szName; // Pointer to name (in user addr space).
- DWORD dwThreadID; // Thread ID (-1=caller thread).
- DWORD dwFlags; // Reserved for future use, must be zero.
+ DWORD dwType; // Must be 0x1000.
+ LPCSTR szName; // Pointer to name (in user addr space).
+ DWORD dwThreadID; // Thread ID (-1=caller thread).
+ DWORD dwFlags; // Reserved for future use, must be zero.
};
#pragma pack(pop)
@@ -432,18 +432,18 @@ struct THREADNAME_INFO
inline
void setCurrentThreadName(const char* threadName)
{
-const DWORD MS_VC_EXCEPTION = 0x406D1388;
-
-THREADNAME_INFO info = {};
- info.dwType = 0x1000;
- info.szName = threadName;
- info.dwThreadID = GetCurrentThreadId();
-
- __try
- {
- ::RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), reinterpret_cast<ULONG_PTR*>(&info));
- }
- __except(EXCEPTION_EXECUTE_HANDLER){}
+ const DWORD MS_VC_EXCEPTION = 0x406D1388;
+
+ THREADNAME_INFO info = {};
+ info.dwType = 0x1000;
+ info.szName = threadName;
+ info.dwThreadID = GetCurrentThreadId();
+
+ __try
+ {
+ ::RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), reinterpret_cast<ULONG_PTR*>(&info));
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) {}
}
#endif
}
diff --git a/zen/type_traits.h b/zen/type_traits.h
index ac7f1a42..c0da43ed 100644
--- a/zen/type_traits.h
+++ b/zen/type_traits.h
@@ -38,11 +38,8 @@ struct ResultType
};
//Herb Sutter's signedness conversion helpers: http://herbsutter.com/2013/06/13/gotw-93-solution-auto-variables-part-2/
-template<class T> inline
-typename std::make_signed<T>::type makeSigned(T t) { return static_cast<std::make_signed_t<T>>(t); }
-
-template<class T> inline
-typename std::make_unsigned<T>::type makeUnsigned(T t) { return static_cast<std::make_unsigned_t<T>>(t); }
+template<class T> inline auto makeSigned (T t) { return static_cast<std::make_signed_t <T>>(t); }
+template<class T> inline auto makeUnsigned(T t) { return static_cast<std::make_unsigned_t<T>>(t); }
//################# Built-in Types ########################
//Example: "IsSignedInt<int>::value" evaluates to "true"
@@ -62,7 +59,7 @@ template <class T> struct IsArithmetic; //IsInteger or IsFloat
/* Detect data or function members of a class by name: ZEN_INIT_DETECT_MEMBER + HasMember_
Example: 1. ZEN_INIT_DETECT_MEMBER(c_str);
- 2. HasMember_c_str<T>::value -> use as boolean
+ 2. HasMember_c_str<T>::value -> use boolean
*/
/* Detect data or function members of a class by name *and* type: ZEN_INIT_DETECT_MEMBER2 + HasMember_
bgstack15