Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/elfmz/far2l.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelfmz <fenix1905@tut.by>2022-11-06 13:58:11 +0300
committerelfmz <fenix1905@tut.by>2022-11-06 13:58:11 +0300
commit6acba431919214b322b03ed5dc4cf16968f59815 (patch)
treef2cf27305e24f4fa57b22751dd542ac84461ce4e
parentd039fdc6f9fa2c6bc5b50abc77e0cdf6543a1a5e (diff)
copy file: fix out of space silently ignored when copying to SMB share (fix #1387)
-rw-r--r--WinPort/src/APIFiles.cpp38
-rw-r--r--WinPort/src/WinPortHandle.cpp15
-rw-r--r--WinPort/src/WinPortHandle.h6
-rw-r--r--far2l/src/copy.cpp7
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;