summaryrefslogtreecommitdiff
path: root/src/libs6rc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs6rc')
-rw-r--r--src/libs6rc/deps-lib/s6rc2
-rw-r--r--src/libs6rc/s6rc_livedir_suffix.c19
-rw-r--r--src/libs6rc/s6rc_livedir_suffixsize.c24
-rw-r--r--src/libs6rc/s6rc_read_uint.c1
-rw-r--r--src/libs6rc/s6rc_servicedir_manage.c16
-rw-r--r--src/libs6rc/s6rc_servicedir_unsupervise.c10
6 files changed, 61 insertions, 11 deletions
diff --git a/src/libs6rc/deps-lib/s6rc b/src/libs6rc/deps-lib/s6rc
index 5e6263d..3768378 100644
--- a/src/libs6rc/deps-lib/s6rc
+++ b/src/libs6rc/deps-lib/s6rc
@@ -5,6 +5,8 @@ s6rc_db_read.o
s6rc_db_read_sizes.o
s6rc_db_read_uint32.o
s6rc_graph_closure.o
+s6rc_livedir_suffix.o
+s6rc_livedir_suffixsize.o
s6rc_lock.o
s6rc_read_uint.o
s6rc_sanitize_dir.o
diff --git a/src/libs6rc/s6rc_livedir_suffix.c b/src/libs6rc/s6rc_livedir_suffix.c
new file mode 100644
index 0000000..98236cd
--- /dev/null
+++ b/src/libs6rc/s6rc_livedir_suffix.c
@@ -0,0 +1,19 @@
+/* ISC license. */
+
+#include <string.h>
+#include <errno.h>
+#include <skalibs/djbunix.h>
+#include <s6-rc/s6rc-utils.h>
+
+ssize_t s6rc_livedir_suffix (char const *live, char *s, size_t n)
+{
+ size_t llen = strlen(live) ;
+ size_t r ;
+ char sfn[llen + 8] ;
+ memcpy(sfn, live, llen) ;
+ memcpy(sfn + llen, "/suffix", 8) ;
+ r = openreadnclose(sfn, s, n) ;
+ if (r < 0) return r ;
+ if (memchr(s, '/', r)) return (errno = EINVAL, 0) ;
+ return r ;
+}
diff --git a/src/libs6rc/s6rc_livedir_suffixsize.c b/src/libs6rc/s6rc_livedir_suffixsize.c
new file mode 100644
index 0000000..b571dad
--- /dev/null
+++ b/src/libs6rc/s6rc_livedir_suffixsize.c
@@ -0,0 +1,24 @@
+/* ISC license. */
+
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <s6-rc/s6rc-utils.h>
+
+int s6rc_livedir_suffixsize (char const *live, size_t *n)
+{
+ struct stat st ;
+ size_t llen = strlen(live) ;
+ char sfn[llen + 8] ;
+ memcpy(sfn, live, llen) ;
+ memcpy(sfn + llen, "/suffix", 8) ;
+ if (stat(sfn, &st) < 0)
+ {
+ if (errno != ENOENT) return 0 ;
+ *n = 0 ;
+ return 1 ;
+ }
+ if (!S_ISREG(st.st_mode)) return (errno = EINVAL, 0) ;
+ *n = st.st_size ;
+ return 1 ;
+}
diff --git a/src/libs6rc/s6rc_read_uint.c b/src/libs6rc/s6rc_read_uint.c
index c9f05be..1f148ac 100644
--- a/src/libs6rc/s6rc_read_uint.c
+++ b/src/libs6rc/s6rc_read_uint.c
@@ -5,6 +5,7 @@
#include <skalibs/types.h>
#include <skalibs/bytestr.h>
#include <skalibs/djbunix.h>
+#include <s6-rc/s6rc-utils.h>
int s6rc_read_uint (char const *file, unsigned int *u)
{
diff --git a/src/libs6rc/s6rc_servicedir_manage.c b/src/libs6rc/s6rc_servicedir_manage.c
index 218c0af..d39d045 100644
--- a/src/libs6rc/s6rc_servicedir_manage.c
+++ b/src/libs6rc/s6rc_servicedir_manage.c
@@ -13,23 +13,24 @@
#include <s6/ftrigw.h>
#include <s6-rc/s6rc-servicedir.h>
-static void rollback (char const *live, char const *s, size_t len)
+static inline void rollback (char const *live, char const *suffix, char const *s, size_t len)
{
while (len)
{
size_t n = strlen(s) + 1 ;
- s6rc_servicedir_unsupervise(live, s, 0) ;
+ s6rc_servicedir_unsupervise(live, suffix, s, 0) ;
s += n ; len -= n ;
}
}
-int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *stamp)
+int s6rc_servicedir_manage (char const *live, char const *suffix, tain_t const *deadline, tain_t *stamp)
{
ftrigr_t a = FTRIGR_ZERO ;
stralloc newnames = STRALLOC_ZERO ;
genalloc ids = GENALLOC_ZERO ; /* uint16_t */
gid_t gid = getgid() ;
size_t livelen = strlen(live) ;
+ size_t suffixlen = strlen(suffix) ;
int ok = 1 ;
int e = 0 ;
DIR *dir ;
@@ -52,7 +53,7 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st
int r ;
uint16_t id ;
char srcfn[livelen + 20 + len] ;
- char dstfn[livelen + 10 + len] ;
+ char dstfn[livelen + 10 + len + suffixlen] ;
memcpy(srcfn, dirfn, livelen + 12) ;
srcfn[livelen + 12] = '/' ;
memcpy(srcfn + livelen + 13, d->d_name, len + 1) ;
@@ -75,7 +76,8 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st
else s6_svc_lock_release(fdlock) ;
memcpy(dstfn, live, livelen) ;
memcpy(dstfn + livelen, "/scandir/", 9) ;
- memcpy(dstfn + livelen + 9, d->d_name, len + 1) ;
+ memcpy(dstfn + livelen + 9, d->d_name, len) ;
+ memcpy(dstfn + livelen + 9 + len, suffix, suffixlen + 1) ;
if (symlink(srcfn, dstfn) < 0)
{
if (!r || errno != EEXIST) goto err ;
@@ -85,7 +87,7 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st
if (!stralloc_catb(&newnames, d->d_name, len + 1))
{
e = errno ;
- s6rc_servicedir_unsupervise(live, d->d_name, 0) ;
+ s6rc_servicedir_unsupervise(live, suffix, d->d_name, 0) ;
goto errn ;
}
}
@@ -125,7 +127,7 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st
closederrn:
ftrigr_end(&a) ;
genalloc_free(uint16_t, &ids) ;
- rollback(live, newnames.s, newnames.len) ;
+ rollback(live, suffix, newnames.s, newnames.len) ;
stralloc_free(&newnames) ;
errno = e ;
return 0 ;
diff --git a/src/libs6rc/s6rc_servicedir_unsupervise.c b/src/libs6rc/s6rc_servicedir_unsupervise.c
index 8b0dbb9..ed95152 100644
--- a/src/libs6rc/s6rc_servicedir_unsupervise.c
+++ b/src/libs6rc/s6rc_servicedir_unsupervise.c
@@ -5,14 +5,16 @@
#include <s6/s6-supervise.h>
#include <s6-rc/s6rc-servicedir.h>
-void s6rc_servicedir_unsupervise (char const *live, char const *name, int keepsupervisor)
+void s6rc_servicedir_unsupervise (char const *live, char const *suffix, char const *name, int keepsupervisor)
{
- size_t namelen = strlen(name) ;
size_t livelen = strlen(live) ;
- char fn[livelen + 14 + namelen] ;
+ size_t suffixlen = strlen(suffix) ;
+ size_t namelen = strlen(name) ;
+ char fn[livelen + 14 + namelen + suffixlen] ;
memcpy(fn, live, livelen) ;
memcpy(fn + livelen, "/scandir/", 9) ;
- memcpy(fn + livelen + 9, name, namelen + 1) ;
+ memcpy(fn + livelen + 9, name, namelen) ;
+ memcpy(fn + livelen + 9 + namelen, suffix, suffixlen + 1) ;
unlink(fn) ;
if (!keepsupervisor)
{