summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/skalibs/unix-transactional.h3
-rw-r--r--src/libunixonacid/atomic_rm_rf.c9
-rw-r--r--src/libunixonacid/atomic_rm_rf_tmp.c32
-rw-r--r--src/libunixonacid/mkdir_unique.c4
4 files changed, 46 insertions, 2 deletions
diff --git a/src/include/skalibs/unix-transactional.h b/src/include/skalibs/unix-transactional.h
index e1c8955..beb27b4 100644
--- a/src/include/skalibs/unix-transactional.h
+++ b/src/include/skalibs/unix-transactional.h
@@ -40,6 +40,9 @@ extern unsigned int openwritenclose_at (int, char const *, char const *, unsigne
extern unsigned int openwritevnclose_at (int, char const *, siovec_t const *, unsigned int) ;
extern int mkdir_unique (stralloc *, char const *, unsigned int) ;
+extern int atomic_rm_rf (char const *) ;
+extern int atomic_rm_rf_tmp (char const *, stralloc *) ;
+
typedef struct dirdescriptor_s dirdescriptor_t, *dirdescriptor_t_ref ;
struct dirdescriptor_s
diff --git a/src/libunixonacid/atomic_rm_rf.c b/src/libunixonacid/atomic_rm_rf.c
new file mode 100644
index 0000000..b7f157b
--- /dev/null
+++ b/src/libunixonacid/atomic_rm_rf.c
@@ -0,0 +1,9 @@
+/* ISC license. */
+
+#include <skalibs/skamisc.h>
+#include <skalibs/unix-transactional.h>
+
+int atomic_rm_rf (char const *filename)
+{
+ return atomic_rm_rf_tmp(filename, &satmp) ;
+}
diff --git a/src/libunixonacid/atomic_rm_rf_tmp.c b/src/libunixonacid/atomic_rm_rf_tmp.c
new file mode 100644
index 0000000..8be5189
--- /dev/null
+++ b/src/libunixonacid/atomic_rm_rf_tmp.c
@@ -0,0 +1,32 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <stdio.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/random.h>
+#include <skalibs/unix-transactional.h>
+
+int atomic_rm_rf_tmp (char const *filename, stralloc *tmp)
+{
+ unsigned int tmpbase = tmp->len ;
+ unsigned int start ;
+ if (!stralloc_cats(tmp, ".skalibs-rmrf-")
+ || !stralloc_cats(tmp, filename)) return -1 ;
+ start = tmp->len ;
+ for (;;)
+ {
+ if (random_sauniquename(tmp, 64) < 0) goto err ;
+ if (!stralloc_0(tmp)) goto err ;
+ if (!rename(filename, tmp->s + tmpbase)) break ;
+ if (errno != EEXIST && errno != ENOTEMPTY) goto err ;
+ tmp->len = start ;
+ }
+ if (rm_rf_in_tmp(tmp, tmpbase) < 0) goto err ;
+ tmp->len = tmpbase ;
+ return 0 ;
+
+err:
+ tmp->len = tmpbase ;
+ return -1 ;
+}
diff --git a/src/libunixonacid/mkdir_unique.c b/src/libunixonacid/mkdir_unique.c
index 523ecef..efc74cc 100644
--- a/src/libunixonacid/mkdir_unique.c
+++ b/src/libunixonacid/mkdir_unique.c
@@ -10,8 +10,8 @@ int mkdir_unique (stralloc *sa, char const *fn, unsigned int mode)
unsigned int base = sa->len ;
int wasnull = !sa->s ;
if (!stralloc_cats(sa, fn)) return 0 ;
- if (!stralloc_cats(sa, "/mkdir_unique")) goto fail ;
- if (random_sauniquename(sa, 8) < 0) goto fail ;
+ if (!stralloc_cats(sa, "/mkdir_unique:")) goto fail ;
+ if (random_sauniquename(sa, 64) < 0) goto fail ;
if (!stralloc_0(sa)) goto fail ;
if (mkdir(sa->s + base, mode) < 0) goto fail ;
sa->len-- ;