From 4044f461408ef2ba7dffb80619268f42b0757f48 Mon Sep 17 00:00:00 2001 From: vng Date: Mon, 5 Apr 2021 21:34:22 +0300 Subject: [PATCH] Fixed bug with empty files. Signed-off-by: vng --- coding/coding_tests/file_data_test.cpp | 19 ++++++++++++++++++- coding/internal/file_data.cpp | 24 +++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/coding/coding_tests/file_data_test.cpp b/coding/coding_tests/file_data_test.cpp index 4a92cd0e87..7244aec6d8 100644 --- a/coding/coding_tests/file_data_test.cpp +++ b/coding/coding_tests/file_data_test.cpp @@ -185,23 +185,40 @@ UNIT_TEST(EmptyFile) std::string const name = "test.empty"; std::string const copy = "test.empty.copy"; + // Check that both files are not exist. + uint64_t sz; + TEST(!GetFileSize(name, sz), ()); + TEST(!GetFileSize(copy, sz), ()); + + // Try to copy non existing file - failed. + TEST(!CopyFileX(name, copy), ()); + + // Again, both files are not exist. + TEST(!GetFileSize(name, sz), ()); + TEST(!GetFileSize(copy, sz), ()); + { + // Create empty file with zero size. FileData f(name, base::FileData::OP_WRITE_TRUNCATE); } - uint64_t sz; + // Check that empty file is on disk. TEST(GetFileSize(name, sz), ()); TEST_EQUAL(sz, 0, ()); + // Do copy. TEST(CopyFileX(name, copy), ()); //TEST(!RenameFileX(name, copy), ()); + // Delete copy file and rename name -> copy. TEST(DeleteFileX(copy), ()); TEST(RenameFileX(name, copy), ()); + // Now we don't have an initial file but have a copy. TEST(!GetFileSize(name, sz), ()); TEST(GetFileSize(copy, sz), ()); TEST_EQUAL(sz, 0, ()); + // Delete copy file. TEST(DeleteFileX(copy), ()); } diff --git a/coding/internal/file_data.cpp b/coding/internal/file_data.cpp index 28c5b10b5b..dba27edd4a 100644 --- a/coding/internal/file_data.cpp +++ b/coding/internal/file_data.cpp @@ -165,6 +165,7 @@ bool GetFileSize(string const & fName, uint64_t & sz) namespace { + bool CheckFileOperationResult(int res, string const & fName) { if (!res) @@ -181,6 +182,12 @@ bool CheckFileOperationResult(int res, string const & fName) return false; } + +bool IsEOF(ifstream & fs) +{ + return fs.peek() == ifstream::traits_type::eof(); +} + } // namespace bool DeleteFileX(string const & fName) @@ -243,7 +250,7 @@ void AppendFileToFile(string const & fromFilename, string const & toFilename) to.open(toFilename, ios::binary | ios::app); auto * buffer = from.rdbuf(); - if (from.peek() != ifstream::traits_type::eof()) + if (!IsEOF(from)) to << buffer; } @@ -258,15 +265,26 @@ bool CopyFileX(string const & fOld, string const & fNew) { ifs.open(fOld.c_str()); ofs.open(fNew.c_str()); + + // If source file is empty - make empty dest file without any errors. + if (IsEOF(ifs)) + return true; + ofs << ifs.rdbuf(); ofs.flush(); return true; } - catch (exception const & ex) + catch (system_error const &) { - LOG(LERROR, ("Failed to copy file from", fOld, "to", fNew, ":", strerror(errno))); + LOG(LWARNING, ("Failed to copy file from", fOld, "to", fNew, ":", strerror(errno))); + } + catch (exception const &) + { + LOG(LERROR, ("Unknown error when coping files:", fOld, "to", fNew, strerror(errno))); } + // Don't care about possible error here .. + (void) DeleteFileX(fNew); return false; }