diff options
author | B Stack <bgstack15@gmail.com> | 2019-03-13 10:36:44 +0000 |
---|---|---|
committer | B Stack <bgstack15@gmail.com> | 2019-03-13 10:36:44 +0000 |
commit | 2c01454a3fea1c29df0aeb208862243cb928b74c (patch) | |
tree | dc226d83311470a23cdf0c02064feb525fcc5096 /zen/file_io.cpp | |
parent | Merge branch '10.9' into 'master' (diff) | |
parent | 10.10 (diff) | |
download | FreeFileSync-2c01454a3fea1c29df0aeb208862243cb928b74c.tar.gz FreeFileSync-2c01454a3fea1c29df0aeb208862243cb928b74c.tar.bz2 FreeFileSync-2c01454a3fea1c29df0aeb208862243cb928b74c.zip |
Merge branch '10.10' into 'master'10.10
10.10
Latest changes:
* New option: synchronize selection
* Dynamically disable unsuitable context menu options
* Support MTP devices without move command
* Fall back to copy/delete when implicitly moving to different device (e.g. symlink)
* Fixed incorrect statistics after parallel move
* Fixed menu button not triggering context menu
* Fixed crash on focus change while message popup is dismissed
* Fixed crash when trying to shrink empty image
* Fixed invisible dialogs when monitor is turned off in multi-monitor setup
* Work around GetFileInformationByHandle error code 58 on WD My Cloud EX
* Changing deletion handling now correctly triggers updated config
* Support root-relative FTP file paths (e.g. FreeNAS)
* Move and rename MTP items as a transaction
* Exclude AppleDouble files (._) via default filter on macOS
* Support home path for FTP folder picker
* Use server default permissions when creating SFTP folder
* Use native OpenSSL AES-CTR rather than libssh2 fallback
* Added context information for cloud connection errors
* Updated translation files
See merge request opensource-tracking/FreeFileSync!7
Diffstat (limited to 'zen/file_io.cpp')
-rw-r--r-- | zen/file_io.cpp | 66 |
1 files changed, 30 insertions, 36 deletions
diff --git a/zen/file_io.cpp b/zen/file_io.cpp index 1c6ab6f2..e788bcfe 100644 --- a/zen/file_io.cpp +++ b/zen/file_io.cpp @@ -14,43 +14,12 @@ using namespace zen; -namespace -{ -//- "filePath" could be a named pipe which *blocks* forever for open()! -//- open() with O_NONBLOCK avoids the block, but opens successfully -//- create sample pipe: "sudo mkfifo named_pipe" -void checkForUnsupportedType(const Zstring& filePath) //throw FileError -{ - struct ::stat fileInfo = {}; - if (::stat(filePath.c_str(), &fileInfo) != 0) //follows symlinks - return; //let the caller handle errors like "not existing" - - if (!S_ISREG(fileInfo.st_mode) && - !S_ISLNK(fileInfo.st_mode) && - !S_ISDIR(fileInfo.st_mode)) - { - auto getTypeName = [](mode_t m) -> std::wstring - { - const wchar_t* name = - S_ISCHR (m) ? L"character device": - S_ISBLK (m) ? L"block device" : - S_ISFIFO(m) ? L"FIFO, named pipe" : - S_ISSOCK(m) ? L"socket" : nullptr; - const std::wstring numFmt = printNumber<std::wstring>(L"0%06o", m & S_IFMT); - return name ? numFmt + L", " + name : numFmt; - }; - throw FileError(replaceCpy(_("Type of item %x is not supported:"), L"%x", fmtPath(filePath)) + L" " + getTypeName(fileInfo.st_mode)); - } -} -} - - - const FileBase::FileHandle FileBase::invalidHandleValue = -1; + const FileBase::FileHandle FileBase::invalidHandleValue_ = -1; FileBase::~FileBase() { - if (fileHandle_ != invalidHandleValue) + if (fileHandle_ != invalidHandleValue_) try { close(); //throw FileError @@ -61,9 +30,9 @@ FileBase::~FileBase() void FileBase::close() //throw FileError { - if (fileHandle_ == invalidHandleValue) + if (fileHandle_ == invalidHandleValue_) throw FileError(replaceCpy(_("Cannot write file %x."), L"%x", fmtPath(getFilePath())), L"Contract error: close() called more than once."); - ZEN_ON_SCOPE_EXIT(fileHandle_ = invalidHandleValue); + ZEN_ON_SCOPE_EXIT(fileHandle_ = invalidHandleValue_); //no need to clean-up on failure here (just like there is no clean on FileOutput::write failure!) => FileOutput is not transactional! @@ -77,7 +46,32 @@ namespace { FileBase::FileHandle openHandleForRead(const Zstring& filePath) //throw FileError, ErrorFileLocked { - checkForUnsupportedType(filePath); //throw FileError; opening a named pipe would block forever! + //- "filePath" could be a named pipe which *blocks* forever for open()! + //- open() with O_NONBLOCK avoids the block, but opens successfully + //- create sample pipe: "sudo mkfifo named_pipe" + struct ::stat fileInfo = {}; + if (::stat(filePath.c_str(), &fileInfo) == 0) //follows symlinks + { + if (!S_ISREG(fileInfo.st_mode) && + !S_ISLNK(fileInfo.st_mode) && + !S_ISDIR(fileInfo.st_mode)) + { + const std::wstring typeName = [m = fileInfo.st_mode] + { + std::wstring name = + S_ISCHR (m) ? L"character device" : + S_ISBLK (m) ? L"block device" : + S_ISFIFO(m) ? L"FIFO, named pipe" : + S_ISSOCK(m) ? L"socket" : L""; + if (!name.empty()) + name += L", "; + return name + printNumber<std::wstring>(L"0%06o", m & S_IFMT); + }(); + throw FileError(replaceCpy(_("Cannot open file %x."), L"%x", fmtPath(filePath)), + _("Unsupported item type.") + L" [" + typeName + L"]"); + } + } + //else: let ::open() fail for errors like "not existing" //don't use O_DIRECT: http://yarchive.net/comp/linux/o_direct.html const FileBase::FileHandle fileHandle = ::open(filePath.c_str(), O_RDONLY | O_CLOEXEC); |