From 65d71ab4b780a5d18a8146eb4567eb8a9105f4fe Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Thu, 13 Aug 2015 12:02:12 +0000 Subject: Add atomic_rm_rf and atomic_rm_rf_tmp --- src/include/skalibs/unix-transactional.h | 3 +++ src/libunixonacid/atomic_rm_rf.c | 9 +++++++++ src/libunixonacid/atomic_rm_rf_tmp.c | 32 ++++++++++++++++++++++++++++++++ src/libunixonacid/mkdir_unique.c | 4 ++-- 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/libunixonacid/atomic_rm_rf.c create mode 100644 src/libunixonacid/atomic_rm_rf_tmp.c (limited to 'src') 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 +#include + +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 +#include +#include +#include +#include +#include + +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-- ; -- cgit v1.2.3