diff options
author | elfmz <fenix1905@tut.by> | 2022-11-06 13:58:11 +0300 |
---|---|---|
committer | elfmz <fenix1905@tut.by> | 2022-11-06 13:58:11 +0300 |
commit | 6acba431919214b322b03ed5dc4cf16968f59815 (patch) | |
tree | f2cf27305e24f4fa57b22751dd542ac84461ce4e | |
parent | d039fdc6f9fa2c6bc5b50abc77e0cdf6543a1a5e (diff) |
copy file: fix out of space silently ignored when copying to SMB share (fix #1387)
-rw-r--r-- | WinPort/src/APIFiles.cpp | 38 | ||||
-rw-r--r-- | WinPort/src/WinPortHandle.cpp | 15 | ||||
-rw-r--r-- | WinPort/src/WinPortHandle.h | 6 | ||||
-rw-r--r-- | far2l/src/copy.cpp | 7 |
4 files changed, 55 insertions, 11 deletions
diff --git a/WinPort/src/APIFiles.cpp b/WinPort/src/APIFiles.cpp index 3836b79d..b1907a26 100644 --- a/WinPort/src/APIFiles.cpp +++ b/WinPort/src/APIFiles.cpp @@ -63,15 +63,45 @@ extern "C" { struct WinPortHandleFile : WinPortHandle { + int fd; + WinPortHandleFile(int fd_ = -1) : fd(fd_) {} virtual ~WinPortHandleFile() { - if (os_call_int(sdc_close, fd) == -1 ){ - fprintf(stderr, "~WinPortHandleFile: error %u closing fd %d", errno, fd); - } + if (fd != -1) { + fprintf(stderr, "~WinPortHandleFile: unclosed fd %d\n", fd); + } } - int fd; + + protected: + bool EnsureClosed() + { + bool out = (fd == -1 || os_call_int(sdc_close, fd) == 0); + if (!out) { + fprintf(stderr, "WinPortHandleFile: error %u closing fd %d\n", errno, fd); + } + + fd = -1; + return out; + } + + virtual bool Cleanup() + { + bool out = EnsureClosed(); + int saved_errno; + if (!out) { + saved_errno = errno; + } + if (!WinPortHandle::Cleanup()) { + return false; + } + if (!out) { + errno = saved_errno; + } + return out; + } + }; diff --git a/WinPort/src/WinPortHandle.cpp b/WinPort/src/WinPortHandle.cpp index ce9e291c..4aef8208 100644 --- a/WinPort/src/WinPortHandle.cpp +++ b/WinPort/src/WinPortHandle.cpp @@ -17,10 +17,18 @@ void WinPortHandle::Reference() ++_refcnt; } -void WinPortHandle::Dereference() +bool WinPortHandle::Dereference() { if (0 == --_refcnt) - OnReleased(); + return Cleanup(); + + return true; +} + +bool WinPortHandle::Cleanup() +{ + delete this; + return true; } static struct WinPortHandles : std::set<WinPortHandle *>, std::mutex @@ -46,8 +54,7 @@ bool WinPortHandle_Deregister(HANDLE h) return false; } } - wph->Dereference(); - return true; + return wph->Dereference(); } diff --git a/WinPort/src/WinPortHandle.h b/WinPort/src/WinPortHandle.h index 937bcbe5..570b8852 100644 --- a/WinPort/src/WinPortHandle.h +++ b/WinPort/src/WinPortHandle.h @@ -15,15 +15,17 @@ class WinPortHandle { std::atomic<unsigned int> _refcnt{0}; +protected: + virtual bool Cleanup(); + public: WinPortHandle(); virtual ~WinPortHandle(); virtual bool WaitHandle(DWORD msec) {return true; } - virtual void OnReleased() {delete this; }; void Reference(); - void Dereference(); + bool Dereference(); }; template <class T> diff --git a/far2l/src/copy.cpp b/far2l/src/copy.cpp index 57f274e9..5487f4ec 100644 --- a/far2l/src/copy.cpp +++ b/far2l/src/copy.cpp @@ -2865,7 +2865,12 @@ void ShellFileTransfer::Do() _DestFile.SetTime(nullptr, nullptr, &_SrcData.ftLastWriteTime, nullptr); } - _DestFile.Close(); + if (!_DestFile.Close()) + { // #1387 + // if file located on old samba share then in out of space condition + // write()-s succeed but close() reports error + throw ErrnoSaver(); + } _Done = true; |