mirror of
https://github.com/GothenburgBitFactory/timewarrior.git
synced 2025-06-26 10:54:28 +02:00
AtomicFile: Add size() and remove() methods
Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
This commit is contained in:
parent
cea2e5d13f
commit
0a4644bfc7
3 changed files with 71 additions and 8 deletions
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include <csignal>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
@ -59,7 +61,9 @@ struct AtomicFile::impl
|
|||
|
||||
bool open ();
|
||||
void close ();
|
||||
size_t size () const;
|
||||
void truncate ();
|
||||
void remove ();
|
||||
void read (std::string& content);
|
||||
void read (std::vector <std::string>& lines);
|
||||
void append (const std::string& content);
|
||||
|
@ -150,6 +154,18 @@ void AtomicFile::impl::close ()
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
size_t AtomicFile::impl::size () const
|
||||
{
|
||||
struct stat s;
|
||||
const char *filename = (is_temp_active) ? temp_file._data.c_str () : real_file._data.c_str ();
|
||||
if (stat (filename, &s))
|
||||
{
|
||||
throw format ("stat error {1}: {2}", errno, strerror (errno));
|
||||
}
|
||||
return s.st_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void AtomicFile::impl::truncate ()
|
||||
{
|
||||
|
@ -165,6 +181,21 @@ void AtomicFile::impl::truncate ()
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void AtomicFile::impl::remove ()
|
||||
{
|
||||
try
|
||||
{
|
||||
temp_file.remove ();
|
||||
is_temp_active = true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
allow_atomics = false;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void AtomicFile::impl::read (std::string& content)
|
||||
{
|
||||
|
@ -233,11 +264,19 @@ void AtomicFile::impl::finalize ()
|
|||
{
|
||||
if (is_temp_active && impl::allow_atomics)
|
||||
{
|
||||
debug (format ("Moving '{1}' -> '{2}'", temp_file._data, real_file._data));
|
||||
if (std::rename (temp_file._data.c_str (), real_file._data.c_str ()))
|
||||
if (temp_file.exists ())
|
||||
{
|
||||
throw format("Failed copying '{1}' to '{2}'. Database corruption possible.",
|
||||
temp_file._data, real_file._data);
|
||||
debug (format ("Moving '{1}' -> '{2}'", temp_file._data, real_file._data));
|
||||
if (std::rename (temp_file._data.c_str (), real_file._data.c_str ()))
|
||||
{
|
||||
throw format("Failed copying '{1}' to '{2}'. Database corruption possible.",
|
||||
temp_file._data, real_file._data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
debug (format ("Removing '{1}'", real_file._data));
|
||||
std::remove (real_file._data.c_str ());
|
||||
}
|
||||
is_temp_active = false;
|
||||
}
|
||||
|
@ -322,12 +361,24 @@ void AtomicFile::close ()
|
|||
pimpl->close ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
size_t AtomicFile::size () const
|
||||
{
|
||||
return pimpl->size ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void AtomicFile::truncate ()
|
||||
{
|
||||
pimpl->truncate ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void AtomicFile::remove ()
|
||||
{
|
||||
pimpl->remove ();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void AtomicFile::read (std::string& content)
|
||||
{
|
||||
|
|
|
@ -48,7 +48,9 @@ public:
|
|||
|
||||
bool open ();
|
||||
void close ();
|
||||
void remove ();
|
||||
void truncate ();
|
||||
size_t size () const;
|
||||
void read (std::string& content);
|
||||
void read (std::vector <std::string>& lines);
|
||||
void append (const std::string& content);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
@ -451,18 +452,27 @@ int test (UnitTest& t)
|
|||
t.fail (test_name);
|
||||
t.diag (std::string ("Expected '" + expected + "' read '" + contents + "'"));
|
||||
}
|
||||
AtomicFile::reset ();
|
||||
|
||||
{
|
||||
AtomicFile test ("test");
|
||||
tempDir.clear ();
|
||||
Path test("test");
|
||||
AtomicFile file(test);
|
||||
file.truncate ();
|
||||
assert (! test.exists ());
|
||||
AtomicFile::finalize_all ();
|
||||
assert (test.exists ());
|
||||
file.remove ();
|
||||
t.is (test.exists (), true, "File not removed before finalize");
|
||||
AtomicFile::finalize_all ();
|
||||
t.is (test.exists (), false, "File is removed after finalize");
|
||||
}
|
||||
|
||||
AtomicFile::reset ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (int, char**)
|
||||
{
|
||||
UnitTest t (20);
|
||||
UnitTest t (22);
|
||||
try
|
||||
{
|
||||
int ret = test (t);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue