mirror of
https://github.com/GothenburgBitFactory/timewarrior.git
synced 2025-06-26 10:54:28 +02:00
AtomicFile: Operate on the target of symlinks
Currently, if an AtomicFile is opened on a symlink, the AtomicFile would end up overwriting the link. This change makes AtomicFiles operate on the targets of the links and not the links themselves. ``` $ test/AtomicFileTest 1..22 ok 1 - AtomicFileTest: Shall not exists before finalize ok 2 - AtomicFileTest: Shall exists after finalize ok 3 - AtomicFileTest: Shall have the correct data ok 4 - AtomicFileTest: Neither shall exist before finalize ok 5 - AtomicFileTest: Both shall exists after finalize ok 6 - AtomicFileTest: First file shall contain the correct data ok 7 - AtomicFileTest: Second file shall contain the correct data ok 8 - AtomicFileTest: Appending does not update original before finalize ok 9 - AtomicFileTest: Finalizing updates the appended data ok 10 - AtomicFileTest: Read from Atomicfile ok 11 - AtomicFileTest: Read from Atomicfile should read unfinalized data ok 12 - AtomicFileTest: Two AtomicFiles should access same temp file (part 1) ok 13 - AtomicFileTest: Two AtomicFiles should access same temp file (part 2) ok 14 - AtomicFileTest: Two AtomicFiles should access same temp file (part 3) ok 15 - AtomicFileTest: File not removed before finalize ok 16 - AtomicFileTest: File is removed after finalize ok 17 - AtomicFileTest: writes to symlinks end up in target ok 18 - AtomicFileTest: shall maintain symlink ok 19 - AtomicFileTest: AtomicFile::write_raw throws on error # skip ok 20 - AtomicFileTest: AtomicFile::finalize_all() throws on error # skip ok 21 - AtomicFileTest: AtomicFile::reset clears failure state # skip ok 22 - AtomicFileTest: AtomicFile::append throws on error # skip ok 23 - AtomicFileTest: AtomicFile::append did not partially fill the file. # skip ok 24 - AtomicFileTest: AtomicFile::append failures prevent finalization # skip ``` Fixes #546 Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
This commit is contained in:
parent
c67a4715f8
commit
7a75210ce1
2 changed files with 48 additions and 2 deletions
|
@ -91,9 +91,19 @@ AtomicFile::impl::impl (const Path& path)
|
||||||
static int s_count = 0;
|
static int s_count = 0;
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
|
|
||||||
str << path._data << '.' << s_pid << '-' << ++s_count << ".tmp";
|
std::string real_path;
|
||||||
|
if (path.is_link())
|
||||||
|
{
|
||||||
|
real_path = path.realpath();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
real_path = path._data;
|
||||||
|
}
|
||||||
|
|
||||||
|
str << real_path << '.' << s_pid << '-' << ++s_count << ".tmp";
|
||||||
temp_file = File (str.str());
|
temp_file = File (str.str());
|
||||||
real_file = File (path);
|
real_file = File (real_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef FIU_ENABLE
|
#ifdef FIU_ENABLE
|
||||||
|
|
||||||
|
@ -160,6 +161,37 @@ int fiu_test (UnitTest& t)
|
||||||
}
|
}
|
||||||
#endif // FIU_ENABLE
|
#endif // FIU_ENABLE
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
int test_symlink (UnitTest& t)
|
||||||
|
{
|
||||||
|
Path link ("link");
|
||||||
|
Path target ("target");
|
||||||
|
File(target).write_raw("empty\n");
|
||||||
|
|
||||||
|
const std::string write_contents = "test file contents\n";
|
||||||
|
|
||||||
|
if (::symlink (target._data.c_str(), link._data.c_str()) != 0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Failed to create link in test_symlink");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
AtomicFile file(link);
|
||||||
|
file.write_raw(write_contents);
|
||||||
|
}
|
||||||
|
AtomicFile::finalize_all ();
|
||||||
|
|
||||||
|
|
||||||
|
// After finalizing we should be able read the data that we wrote through the
|
||||||
|
// target
|
||||||
|
std::string read_contents;
|
||||||
|
AtomicFile::read (target, read_contents);
|
||||||
|
t.is(read_contents, write_contents, "AtomicFileTest: writes to symlinks end up in target");
|
||||||
|
t.is (link.is_link (), true, "AtomicFileTest: shall maintain symlink");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
int test (UnitTest& t)
|
int test (UnitTest& t)
|
||||||
{
|
{
|
||||||
|
@ -382,6 +414,10 @@ int test (UnitTest& t)
|
||||||
AtomicFile::finalize_all ();
|
AtomicFile::finalize_all ();
|
||||||
t.is (test.exists (), false, "AtomicFileTest: File is removed after finalize");
|
t.is (test.exists (), false, "AtomicFileTest: File is removed after finalize");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tempDir.clear();
|
||||||
|
test_symlink(t);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue