diff options
Diffstat (limited to 'zen')
-rw-r--r-- | zen/dir_watcher.cpp | 2 | ||||
-rw-r--r-- | zen/dir_watcher.h | 2 | ||||
-rw-r--r-- | zen/file_access.cpp | 12 | ||||
-rw-r--r-- | zen/file_io.cpp | 2 | ||||
-rw-r--r-- | zen/file_io.h | 2 | ||||
-rw-r--r-- | zen/file_traverser.cpp | 14 | ||||
-rw-r--r-- | zen/format_unit.cpp | 3 | ||||
-rw-r--r-- | zen/i18n.h | 40 | ||||
-rw-r--r-- | zen/recycler.cpp | 2 | ||||
-rw-r--r-- | zen/shell_execute.h | 2 | ||||
-rw-r--r-- | zen/symlink_target.h | 6 | ||||
-rw-r--r-- | zen/tick_count.h | 2 | ||||
-rw-r--r-- | zen/time.h | 2 |
13 files changed, 52 insertions, 39 deletions
diff --git a/zen/dir_watcher.cpp b/zen/dir_watcher.cpp index bb78939f..00b48b4f 100644 --- a/zen/dir_watcher.cpp +++ b/zen/dir_watcher.cpp @@ -223,7 +223,7 @@ public: //async I/O is a resource that needs to be guarded since it will write to local variable "buffer"! auto guardAio = zen::makeGuard<ScopeGuardRunMode::ON_EXIT>([&] { - //Canceling Pending I/O Operations: http://msdn.microsoft.com/en-us/library/aa363789(v=vs.85).aspx + //Canceling Pending I/O Operations: https://msdn.microsoft.com/en-us/library/aa363789 #ifdef ZEN_WIN_VISTA_AND_LATER if (::CancelIoEx(hDir, &overlapped) /*!= FALSE*/ || ::GetLastError() != ERROR_NOT_FOUND) #else diff --git a/zen/dir_watcher.h b/zen/dir_watcher.h index ddb3dbb9..eb0bd695 100644 --- a/zen/dir_watcher.h +++ b/zen/dir_watcher.h @@ -15,7 +15,7 @@ namespace zen { -//Windows: ReadDirectoryChangesW http://msdn.microsoft.com/en-us/library/aa365465(v=vs.85).aspx +//Windows: ReadDirectoryChangesW https://msdn.microsoft.com/en-us/library/aa365465 //Linux: inotify http://linux.die.net/man/7/inotify //OS X: kqueue http://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/kqueue.2.html diff --git a/zen/file_access.cpp b/zen/file_access.cpp index 78da0220..11f61291 100644 --- a/zen/file_access.cpp +++ b/zen/file_access.cpp @@ -1199,7 +1199,7 @@ void copyItemPermissions(const Zstring& sourcePath, const Zstring& targetPath, P //Note: trying to copy SACL (SACL_SECURITY_INFORMATION) may return ERROR_PRIVILEGE_NOT_HELD (1314) on Samba shares. This is not due to missing privileges! //However, this is okay, since copying NTFS permissions doesn't make sense in this case anyway - //the following privilege may be required according to http://msdn.microsoft.com/en-us/library/aa364399(VS.85).aspx (although not needed nor active in my tests) + //the following privilege may be required according to https://msdn.microsoft.com/en-us/library/aa364399 (although not needed nor active in my tests) activatePrivilege(SE_BACKUP_NAME); //throw FileError //enable privilege: required to copy owner information @@ -1259,14 +1259,14 @@ void copyItemPermissions(const Zstring& sourcePath, const Zstring& targetPath, P PACL dacl = nullptr; PACL sacl = nullptr; - //File Security and Access Rights: http://msdn.microsoft.com/en-us/library/aa364399(v=VS.85).aspx - //SECURITY_INFORMATION Access Rights: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379573(v=vs.85).aspx + //File Security and Access Rights: https://msdn.microsoft.com/en-us/library/aa364399 + //SECURITY_INFORMATION Access Rights: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379573 const HANDLE hSource = ::CreateFile(applyLongPathPrefix(source).c_str(), READ_CONTROL | ACCESS_SYSTEM_SECURITY, //ACCESS_SYSTEM_SECURITY required for SACL access FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | (procSl == SYMLINK_DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), //FILE_FLAG_BACKUP_SEMANTICS needed to open a directory + FILE_FLAG_BACKUP_SEMANTICS | (procSl == SymLinkHandling::DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), //FILE_FLAG_BACKUP_SEMANTICS needed to open a directory nullptr); if (hSource == INVALID_HANDLE_VALUE) throw FileError @@ -1303,7 +1303,7 @@ void copyItemPermissions(const Zstring& sourcePath, const Zstring& targetPath, P FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, // dwShareMode nullptr, // lpSecurityAttributes OPEN_EXISTING, // dwCreationDisposition - FILE_FLAG_BACKUP_SEMANTICS | (procSl == SYMLINK_DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), // dwFlagsAndAttributes + FILE_FLAG_BACKUP_SEMANTICS | (procSl == SymLinkHandling::DIRECT ? FILE_FLAG_OPEN_REPARSE_POINT : 0), // dwFlagsAndAttributes nullptr); // hTemplateFile }); @@ -2177,7 +2177,7 @@ InSyncAttributes copyFileWindowsDefault(const Zstring& sourceFile, //throw FileE //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 + //if (vistaOrLater()) //see https://blogs.technet.microsoft.com/askperf/2007/05/08/slow-large-file-copy-issues/ // copyFlags |= COPY_FILE_NO_BUFFERING; //no perf difference at worst, improvement for large files (20% in test NTFS -> NTFS) // - this flag may cause file corruption! http://www.freefilesync.org/forum/viewtopic.php?t=1857 // - documentation on CopyFile2() even states: "It is not recommended to pause copies that are using this flag." diff --git a/zen/file_io.cpp b/zen/file_io.cpp index 3891abe6..d0a1bfa3 100644 --- a/zen/file_io.cpp +++ b/zen/file_io.cpp @@ -84,7 +84,7 @@ FileInput::FileInput(const Zstring& filepath) : //throw FileError, ErrorFileLock 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) + /* possible values: (Reference https://msdn.microsoft.com/en-us/library/aa363858#caching_behavior) FILE_FLAG_NO_BUFFERING FILE_FLAG_RANDOM_ACCESS FILE_FLAG_SEQUENTIAL_SCAN diff --git a/zen/file_io.h b/zen/file_io.h index 261829cd..23296c6c 100644 --- a/zen/file_io.h +++ b/zen/file_io.h @@ -55,7 +55,7 @@ public: FileInput(FileHandle handle, const Zstring& filepath); //takes ownership! ~FileInput(); - //Windows: better use 64kB ?? https://technet.microsoft.com/en-us/library/cc938632.aspx + //Windows: better use 64kB ?? https://technet.microsoft.com/en-us/library/cc938632 //Linux: use st_blksize? size_t getBlockSize() const { return 128 * 1024; } size_t tryRead(void* buffer, size_t bytesToRead); //throw FileError; may return short, only 0 means EOF! => CONTRACT: bytesToRead > 0! diff --git a/zen/file_traverser.cpp b/zen/file_traverser.cpp index 89eb6e48..bedc9154 100644 --- a/zen/file_traverser.cpp +++ b/zen/file_traverser.cpp @@ -113,7 +113,7 @@ void zen::traverseFolder(const Zstring& dirPath, struct ::dirent* dirEntry = nullptr; if (::readdir_r(folder, reinterpret_cast< ::dirent*>(&buffer[0]), &dirEntry) != 0) THROW_LAST_FILE_ERROR(replaceCpy(_("Cannot enumerate directory %x."), L"%x", fmtPath(dirPath)), L"readdir_r"); - //don't retry but restart dir traversal on error! http://blogs.msdn.com/b/oldnewthing/archive/2014/06/12/10533529.aspx + //don't retry but restart dir traversal on error! https://blogs.msdn.microsoft.com/oldnewthing/20140612-00/?p=753/ if (!dirEntry) //no more items return; @@ -124,22 +124,22 @@ void zen::traverseFolder(const Zstring& dirPath, if (itemNameRaw[0] == '.' && (itemNameRaw[1] == 0 || (itemNameRaw[1] == '.' && itemNameRaw[2] == 0))) continue; -#ifdef ZEN_MAC - //see native_traverser_impl.h: + +#ifdef ZEN_MAC //normalize all text input (see see native_traverser_impl.h) Zstring itemName; try { - itemName = osx::convertToPrecomposedUtf(itemNameRaw); //throw SysError + itemName = osx::normalizeUtfForPosix(itemNameRaw); //throw SysError } - catch (const SysError& e) //failure is not an item-level error since we don't have the proper decomposed name!!! + catch (const SysError& e) //failure is not an item-level error since we don't know the normalized name yet!!! { throw FileError(replaceCpy(_("Cannot enumerate directory %x."), L"%x", fmtPath(dirPath)), - L"Failed to generate precomposed file name: " + fmtPath(itemNameRaw) + L"\n" + e.toString()); //too obscure to warrant translation + L"Failed to generate normalized file name: " + fmtPath(itemNameRaw) + L"\n" + e.toString()); //too obscure to warrant translation } #else const Zstring& itemName = itemNameRaw; #endif - if (itemName.empty()) //checks result of osx::convertToPrecomposedUtf, too! + if (itemName.empty()) //checks result of osx::normalizeUtfForPosix, too! throw FileError(replaceCpy(_("Cannot enumerate directory %x."), L"%x", fmtPath(dirPath)), L"readdir_r: Data corruption; item with empty name."); const Zstring& itemPath = appendSeparator(dirPath) + itemName; diff --git a/zen/format_unit.cpp b/zen/format_unit.cpp index a880552e..6a0e1668 100644 --- a/zen/format_unit.cpp +++ b/zen/format_unit.cpp @@ -222,7 +222,7 @@ private: fmt.lpDecimalSep = &decimalSep[0]; //not used fmt.lpThousandSep = &thousandSep[0]; - //convert LOCALE_SGROUPING to Grouping: http://blogs.msdn.com/b/oldnewthing/archive/2006/04/18/578251.aspx + //convert LOCALE_SGROUPING to Grouping: https://blogs.msdn.microsoft.com/oldnewthing/20060418-11/?p=31493/ replace(grouping, L';', L""); if (endsWith(grouping, L'0')) grouping.pop_back(); @@ -382,7 +382,6 @@ Opt<std::int64_t> zen::mtpVariantTimetoUtc(double localVarTime) //returns empty return NoValue(); #endif - return filetimeToTimeT(utcFiletime); } @@ -45,7 +45,7 @@ private: }; void setTranslator(std::unique_ptr<const TranslationHandler>&& newHandler); //take ownership -const TranslationHandler* getTranslator(); +std::shared_ptr<const TranslationHandler> getTranslator(); @@ -65,7 +65,7 @@ namespace implementation inline std::wstring translate(const std::wstring& text) { - if (const TranslationHandler* t = getTranslator()) + if (std::shared_ptr<const TranslationHandler> t = getTranslator()) //std::shared_ptr => temporarily take (shared) ownership while using the interface! return t->translate(text); return text; @@ -79,7 +79,7 @@ std::wstring translate(const std::wstring& singular, const std::wstring& plural, { assert(contains(plural, L"%x")); - if (const TranslationHandler* t = getTranslator()) + if (std::shared_ptr<const TranslationHandler> t = getTranslator()) { std::wstring translation = t->translate(singular, plural, n); assert(!contains(translation, L"%x")); @@ -99,11 +99,12 @@ std::wstring translate(const std::wstring& singular, const std::wstring& plural, inline -const TranslationHandler*& getTranslationInstance() +std::shared_ptr<const TranslationHandler>*& getTranslationInstance() { - //avoid static destruction order fiasco: there may be accesses to "getTranslator()" during process shutdown e.g. show message in debug_minidump.cpp! - //=> use POD instead of a std::unique_ptr<>!!! - static const TranslationHandler* inst = nullptr; //external linkage even in header! + //avoid static destruction order fiasco: there may be accesses to "getTranslator()" during process shutdown + //e.g. show message in debug_minidump.cpp or some detached thread assembling an error message! + //=> use POD instead of a plain std::shared_ptr<>!!! + static std::shared_ptr<const TranslationHandler>* inst = nullptr; //external linkage even in header! return inst; } @@ -112,28 +113,41 @@ struct CleanUpTranslationHandler { ~CleanUpTranslationHandler() { - const TranslationHandler*& handler = getTranslationInstance(); - assert(!handler); //clean up at a better time rather than during static destruction! potential MT issues!? + std::shared_ptr<const TranslationHandler>*& handler = getTranslationInstance(); + assert(!handler); //clean up at a better time rather than during static destruction! MT issues! delete handler; handler = nullptr; //getTranslator() may be called even after static objects of this translation unit are destroyed! } }; } +//setTranslator/getTranslator() operating on a global are obviously racy for MT usage +//=> make them fast to cover the rare case of a language change and the not-so-rare case of language clean-up during shutdown +//=> can't synchronize with std::mutex which is non-POD and again leads to global destruction order fiasco +//=> return std::shared_ptr to let instance life time be handled by caller (MT!) inline void setTranslator(std::unique_ptr<const TranslationHandler>&& newHandler) { static implementation::CleanUpTranslationHandler cuth; //external linkage even in header! - const TranslationHandler*& handler = implementation::getTranslationInstance(); - delete handler; - handler = newHandler.release(); + std::shared_ptr<const TranslationHandler>*& handler = implementation::getTranslationInstance(); + auto tmp = handler; + handler = nullptr; + delete tmp; + if (newHandler) + handler = new std::shared_ptr<const TranslationHandler>(std::move(newHandler)); } inline -const TranslationHandler* getTranslator() { return implementation::getTranslationInstance(); } +std::shared_ptr<const TranslationHandler> getTranslator() +{ + std::shared_ptr<const TranslationHandler>*& handler = implementation::getTranslationInstance(); + if (handler) + return *handler; + return nullptr; +} } #endif //I18_N_H_3843489325044253425456 diff --git a/zen/recycler.cpp b/zen/recycler.cpp index 59d2729a..32ba7cb0 100644 --- a/zen/recycler.cpp +++ b/zen/recycler.cpp @@ -212,7 +212,7 @@ bool zen::recycleBinExists(const Zstring& dirPath, const std::function<void ()>& //4. check directory existence of "C:\$Recycle.Bin, C:\RECYCLER, C:\RECYCLED" // -> not upward-compatible, wrong result for subst-alias: recycler assumed existing, although it is not! - //5. alternative approach a'la Raymond Chen: http://blogs.msdn.com/b/oldnewthing/archive/2008/09/18/8956382.aspx + //5. alternative approach a'la Raymond Chen: https://blogs.msdn.microsoft.com/oldnewthing/20080918-00/?p=20843/ //caveat: might not be reliable, e.g. "subst"-alias of volume contains "$Recycle.Bin" although recycler is not available! /* diff --git a/zen/shell_execute.h b/zen/shell_execute.h index 060ba84d..ce34f067 100644 --- a/zen/shell_execute.h +++ b/zen/shell_execute.h @@ -42,7 +42,7 @@ bool shellExecuteImpl(Function fillExecInfo, ExecutionType type) execInfo.fMask = type == EXEC_TYPE_SYNC ? (SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC) : 0; //don't use SEE_MASK_ASYNCOK -> different async mode than the default which returns successful despite errors! execInfo.fMask |= SEE_MASK_FLAG_NO_UI; //::ShellExecuteEx() shows a non-blocking pop-up dialog on errors -> we want a blocking one - //for the record, SEE_MASK_UNICODE does nothing: http://blogs.msdn.com/b/oldnewthing/archive/2014/02/27/10503519.aspx + //for the record, SEE_MASK_UNICODE does nothing: https://blogs.msdn.microsoft.com/oldnewthing/20140227-00/?p=1643/ fillExecInfo(execInfo); diff --git a/zen/symlink_target.h b/zen/symlink_target.h index c4e166e8..a1f48884 100644 --- a/zen/symlink_target.h +++ b/zen/symlink_target.h @@ -84,7 +84,7 @@ Zstring getSymlinkRawTargetString_impl(const Zstring& linkPath) //throw FileErro { using namespace zen; #ifdef ZEN_WIN - //FSCTL_GET_REPARSE_POINT: http://msdn.microsoft.com/en-us/library/aa364571(VS.85).aspx + //FSCTL_GET_REPARSE_POINT: https://msdn.microsoft.com/en-us/library/aa364571 //reading certain symlinks/junctions requires admin rights! try @@ -213,9 +213,9 @@ Zstring getResolvedSymlinkPath(const Zstring& linkPath) { return getResolvedSyml #ifdef ZEN_WIN /* Reparse Point Tags - http://msdn.microsoft.com/en-us/library/windows/desktop/aa365511(v=vs.85).aspx + https://msdn.microsoft.com/en-us/library/windows/desktop/aa365511 WIN32_FIND_DATA structure - http://msdn.microsoft.com/en-us/library/windows/desktop/aa365740(v=vs.85).aspx + https://msdn.microsoft.com/en-us/library/windows/desktop/aa365740 The only surrogate reparse points are; IO_REPARSE_TAG_MOUNT_POINT diff --git a/zen/tick_count.h b/zen/tick_count.h index 647876fb..89910e14 100644 --- a/zen/tick_count.h +++ b/zen/tick_count.h @@ -122,7 +122,7 @@ TickVal getTicks() //return !isValid() on error LARGE_INTEGER now = {}; if (!::QueryPerformanceCounter(&now)) return TickVal(); - //detailed info about QPC: http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408%28v=vs.85%29.aspx + //detailed info about QPC: https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408 //- MSDN: "No need to set the thread affinity" #elif defined ZEN_LINUX @@ -154,7 +154,7 @@ struct GetFormat<FormatIsoDateTimeTag> //%Y-%m-%d %H:%M:%S - e.g. 2001-08-23 14: //strftime() craziness on invalid input: -// VS 2010: CRASH unless "_invalid_parameter_handler" is set: http://msdn.microsoft.com/en-us/library/ksazx244.aspx +// VS 2010: CRASH unless "_invalid_parameter_handler" is set: https://msdn.microsoft.com/en-us/library/ksazx244.aspx // GCC: returns 0, apparently no crash. Still, considering some clib maintainer's comments, we should expect the worst! inline size_t strftimeWrap_impl(char* buffer, size_t bufferSize, const char* format, const std::tm* timeptr) |