summaryrefslogtreecommitdiff
path: root/src/common/lock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/lock.cpp')
-rw-r--r--src/common/lock.cpp46
1 files changed, 33 insertions, 13 deletions
diff --git a/src/common/lock.cpp b/src/common/lock.cpp
index 2ba9a0a..82856e1 100644
--- a/src/common/lock.cpp
+++ b/src/common/lock.cpp
@@ -1,36 +1,56 @@
-#include <unistd.h>
-#include <stdio.h>
#include "lock.hpp"
+
+#include <unistd.h>
+
+#include <cstdio>
+
+#include "cxxstdio.hpp"
#include "socket.hpp"
+#include "../poison.hpp"
+
+/// number of backups to keep
+static
+const int backup_count = 10;
+
/// Protected file writing
/// (Until the file is closed, it keeps the old file)
// Start writing a tmpfile
-FILE *lock_fopen (const char *filename, int *info)
+FILE *lock_fopen(const char *filename, int *info)
{
- char newfile[512];
FILE *fp;
- int no = getpid ();
+ int no = getpid();
// Get a filename that doesn't already exist
+ std::string newfile;
do
{
- sprintf (newfile, "%s_%d.tmp", filename, no++);
+ newfile = STRPRINTF("%s_%d.tmp", filename, no++);
+ fp = fopen_(newfile.c_str(), "wx");
}
- while ((fp = fopen_ (newfile, "r")) && (fclose_ (fp), 1));
+ while (!fp);
*info = --no;
- return fopen_ (newfile, "w");
+ return fp;
}
// Delete the old file and rename the new file
-void lock_fclose (FILE * fp, const char *filename, int *info)
+void lock_fclose(FILE *fp, const char *filename, int *info)
{
- char newfile[512];
if (fp)
{
- fclose_ (fp);
- sprintf (newfile, "%s_%d.tmp", filename, *info);
- rename (newfile, filename);
+ fclose_(fp);
+ int n = backup_count;
+ std::string old_filename = STRPRINTF("%s.%d", filename, n);
+ while (--n)
+ {
+ std::string newer_filename = STRPRINTF("%s.%d", filename, n);
+ rename(newer_filename.c_str(), old_filename.c_str());
+ old_filename = std::move(newer_filename);
+ }
+ rename(filename, old_filename.c_str());
+
+ std::string tmpfile = STRPRINTF("%s_%d.tmp", filename, *info);
+ rename(tmpfile.c_str(), filename);
}
}