diff options
Diffstat (limited to 'src/libs6rc')
| -rw-r--r-- | src/libs6rc/deps-lib/s6rc | 2 | ||||
| -rw-r--r-- | src/libs6rc/s6rc_repo_set_compile.c | 114 | ||||
| -rw-r--r-- | src/libs6rc/s6rc_repo_sync.c | 33 |
3 files changed, 138 insertions, 11 deletions
diff --git a/src/libs6rc/deps-lib/s6rc b/src/libs6rc/deps-lib/s6rc index e4a3027..b57ca05 100644 --- a/src/libs6rc/deps-lib/s6rc +++ b/src/libs6rc/deps-lib/s6rc @@ -15,6 +15,7 @@ s6rc_lock.o s6rc_read_uint.o s6rc_repo_cleanup.o s6rc_repo_lock.o +s6rc_repo_set_compile.o s6rc_repo_sync.o s6rc_sanitize_dir.o s6rc_servicedir_internal.o @@ -27,3 +28,4 @@ s6rc_servicedir_unsupervise.o s6rc_type_check.o -ls6 -lskarnet +${SPAWN_LIB} diff --git a/src/libs6rc/s6rc_repo_set_compile.c b/src/libs6rc/s6rc_repo_set_compile.c new file mode 100644 index 0000000..477549a --- /dev/null +++ b/src/libs6rc/s6rc_repo_set_compile.c @@ -0,0 +1,114 @@ +/* ISC license. */ + +#include <skalibs/bsdsnowflake.h> + +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> + +#include <skalibs/posixplz.h> +#include <skalibs/types.h> +#include <skalibs/tai.h> +#include <skalibs/cspawn.h> +#include <skalibs/strerr.h> +#include <skalibs/djbunix.h> +#include <skalibs/unix-transactional.h> + +#include <s6-rc/config.h> +#include <s6-rc/repo.h> + +int s6rc_repo_set_compile (char const *repo, char const *set, char const *const *subs, size_t nsubs, char *oldc, unsigned int verbosity, char const *fdhuser) +{ + size_t repolen = strlen(repo) ; + size_t setlen = strlen(repo) ; + size_t totsublen = 0 ; + char newc[S6RC_REPO_SET_COMPILE_BUFLEN(repolen, setlen)] ; + memcpy(newc, repo, repolen) ; + memcpy(newc + repolen, "/compiled/.", 11) ; + memcpy(newc + repolen + 11, set, setlen) ; + newc[repolen + 11 + setlen] = ':' ; + timestamp_g(newc + repolen + 12 + setlen) ; + memcpy(newc + repolen + 37 + setlen, ":XXXXXX", 8) ; + memcpy(oldc, newc, repolen + 10) ; + if (mkntemp(newc) == -1) { strerr_warnfu2sys("mkntemp ", newc) ; return -1 ; } + for (size_t i = 0 ; i < nsubs ; i++) totsublen += strlen(subs[i]) + 1 ; + + { + pid_t pid ; + size_t m = 0 ; + int wstat ; + char const *argv[9 + nsubs + !nsubs] ; + char fmtv[UINT_FMT] ; + char src[(nsubs + !nsubs) * (repolen + 10 + setlen) + totsublen] ; + char *w = src ; + fmtv[uint_fmt(fmtv, verbosity)] = 0 ; + argv[m++] = S6RC_BINPREFIX "s6-rc-compile" ; + argv[m++] = "-v"; + argv[m++] = fmtv ; + argv[m++] = "-b" ; + if (fdhuser) + { + argv[m++] = "-h" ; + argv[m++] = fdhuser ; + } + argv[m++] = "--" ; + argv[m++] = newc ; + if (nsubs) + { + for (size_t i = 0 ; i < nsubs ; i++) + { + size_t sublen = strlen(subs[i]) ; + argv[m++] = w ; + memcpy(w, repo, repolen) ; w += repolen ; + memcpy(w, "/sources/", 9) ; w += 9 ; + memcpy(w, set, setlen) ; w += setlen ; + *w++ = '/' ; + memcpy(w, subs[i], sublen+1) ; w += sublen + 1 ; + } + } + else + { + argv[m++] = w ; + memcpy(w, repo, repolen) ; w += repolen ; + memcpy(w, "/sources/", 9) ; w += 9 ; + memcpy(w, set, setlen+1) ; w += setlen+1 ; + } + argv[m++] = 0 ; + pid = cspawn(argv[0], argv, (char const *const *)environ, 0, 0, 0) ; + if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return -1 ; } + if (wait_pid(pid, &wstat) == -1) + { + strerr_warnfu2sys("wait for ", argv[0]) ; + return -1 ; + } + if (WIFSIGNALED(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; + strerr_warnf3x(argv[0], " crashed with signal ", fmt) ; + return -1 ; + } + if (WEXITSTATUS(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ; + strerr_warnf3x(argv[0], " exited with code ", fmt) ; + return (WEXITSTATUS(wstat) == 1) - 1 ; + } + } + { + char fn[repolen + setlen + 11] ; + memcpy(fn, newc, repolen + 10) ; + memcpy(fn + repolen + 10, set, setlen + 1) ; + if (!atomic_symlink4(newc + repolen + 10, fn, oldc + repolen + 10, repolen + setlen + 45)) + { + int e = errno ; + rm_rf(newc) ; + errno = e ; + strerr_warnfu4sys("atomically make a ", fn, " symlink pointing to ", newc + repolen + 10) ; + return -1 ; + } + } + return 1 + !!oldc[repolen + 10] ; +} diff --git a/src/libs6rc/s6rc_repo_sync.c b/src/libs6rc/s6rc_repo_sync.c index 1fb8d65..4341bee 100644 --- a/src/libs6rc/s6rc_repo_sync.c +++ b/src/libs6rc/s6rc_repo_sync.c @@ -24,13 +24,13 @@ static inline void cleanup (char const *fn) errno = e ; } -int s6rc_repo_sync (char const *repo, char const *const *sources, size_t sourceslen, unsigned int verbosity) +int s6rc_repo_sync (char const *repo, char const *const *sources, size_t sourceslen, unsigned int verbosity, char const *fdhuser) { stralloc sa = STRALLOC_ZERO ; size_t repolen = strlen(repo) ; - char newdir[repolen + 24] ; + char newdir[repolen + 29] ; memcpy(newdir, repo, repolen) ; - memcpy(newdir + repolen, "/.everything:cur:XXXXXX", 24) ; + memcpy(newdir + repolen, "/sources/..everything:XXXXXX", 29) ; if (!mkdtemp(newdir)) { strerr_warnfu2sys("mkdtemp ", newdir) ; @@ -56,11 +56,11 @@ int s6rc_repo_sync (char const *repo, char const *const *sources, size_t sources if (d->d_name[0] == '.') continue ; len = strlen(d->d_name) ; { - char dst[repolen + 25 + len] ; + char dst[repolen + 30 + len] ; char src[srclen + len + 2] ; - memcpy(dst, newdir, repolen + 23) ; - dst[repolen + 23] = '/' ; - memcpy(dst + repolen + 24, d->d_name, len+1) ; + memcpy(dst, newdir, repolen + 28) ; + dst[repolen + 28] = '/' ; + memcpy(dst + repolen + 29, d->d_name, len+1) ; memcpy(src, sources[i], srclen) ; src[srclen] = '/' ; memcpy(src + srclen + 1, d->d_name, len+1) ; @@ -116,17 +116,28 @@ int s6rc_repo_sync (char const *repo, char const *const *sources, size_t sources } { - char curdir[repolen + 13] ; + char curdir[repolen + 21] ; memcpy(curdir, repo, repolen) ; - memcpy(curdir + repolen, "/.everything", 13) ; - if (!atomic_symlink(newdir + repolen + 1, curdir, "tmp")) goto err ; + memcpy(curdir + repolen, "/sources/.everything", 21) ; + if (!atomic_symlink4(newdir + repolen + 1, curdir, 0, 0)) goto err ; } stralloc_free(&sa) ; - return s6rc_repo_cleanup(repo) ; + if (!s6rc_repo_cleanup(repo)) return 0 ; + + { + size_t buflen = S6RC_REPO_SET_COMPILE_BUFLEN(repolen, sizeof(".everything") - 1) ; + char oldc[buflen] ; + int r = s6rc_repo_set_compile(repo, ".everything", 0, 0, oldc, verbosity, fdhuser) ; + if (r <= 0) goto err0 ; + if (r == 2) rm_rf(oldc) ; + } + + return 1 ; err: stralloc_free(&sa) ; + err0: cleanup(newdir) ; return 0 ; } |
