package

simple and robust package manager
Log | Files | Refs | README

commit 97aa5841ff3d7d66e8adabd27464983089575df0
parent bd6163e1cb319b01958a621ae4755fc0accf0010
Author: Josuah Demangeon <mail@josuah.net>
Date:   Sun, 13 Jan 2019 16:29:44 +0100

wip parallel build support

Diffstat:
Alock.h | 10++++++++++
Mpack-add.c | 27+++++++++++----------------
Mpack.c | 77++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
3 files changed, 71 insertions(+), 43 deletions(-)

diff --git a/lock.h b/lock.h @@ -0,0 +1,10 @@ +#ifndef LOCK_H +#define LOCK_H + +#include <fcntl.h> + +#define lock_shared(fd) (!flock((fd), LOCK_SH)) +#define lock_exclusive(fd) (!flock((fd), LOCK_EX)) +#define lock_release(fd) (!flock((fd), LOCK_UN)) + +#endif diff --git a/pack-add.c b/pack-add.c @@ -19,25 +19,26 @@ die_nomem(void) } void -step(pack const *p, char const *cmd, char const *log, char const *dir) +step(pack const *p, char const *cmd char const *dir, char const *sub) { int x; char fmt[4]; buffer_puts(buffer_2, " "); - buffer_puts(buffer_2, cmd + (str_start(cmd, "pack-") ? 5 : 0)); + buffer_puts(buffer_2, sub); buffer_puts(buffer_2, " "); buffer_flush(buffer_2); - if ((x = pack_step(p, cmd, log, dir)) == 0) return; + if ((x = pack_step(p, cmd, log, dir, sub)) == 0) return; fmt_long(fmt, x); buffer_puts(buffer_2, "< exit "); buffer_puts(buffer_2, fmt); buffer_puts(buffer_2, "\n"); buffer_flush(buffer_2); - if (dir && !pack_remove(p, dir)) - log_errsys6("deleting ", dir, "/", p->name, "/", p->ver); + + if (dir && !pack_remove(p, dir, char const *sub)) + log_errsys6("deleting .../", sub, "/", p->name, "/", p->ver); exit(100); } @@ -47,20 +48,14 @@ main(int argc, char **argv) genalloc ga; size_t i; pack p; + char *dir; char *def; - char *log; - char *tar; - char *src; - char *out; if (argc != 2) log_usage(*argv, "package[/version]"); ++argv; + dir = env_get("PACK_DIR"); if (!dir) dir = PACK_DIR; def = env_get("PACK_DEF"); if (!def) def = PACK_DEF; - log = env_get("PACK_LOG"); if (!log) log = PACK_LOG; - tar = env_get("PACK_TAR"); if (!tar) tar = PACK_TAR; - src = env_get("PACK_SRC"); if (!src) src = PACK_SRC; - out = env_get("PACK_OUT"); if (!out) out = PACK_OUT; if (!fs_isdir(def)) log_diesys1(101, def); @@ -90,9 +85,9 @@ main(int argc, char **argv) buffer_puts(buffer_2, " "); buffer_flush(buffer_2); - if (pack_isdone(p, out)) goto step_install; - if (pack_isdone(p, src)) goto step_build; - if (pack_isdone(p, tar)) goto step_tar; + if (pack_isdone(p, dir, "run")) goto step_install; + if (pack_isdone(p, dir, "src")) goto step_build; + if (pack_isdone(p, dir, "tar")) goto step_tar; step(p, "pack-get", log, tar); step_tar: diff --git a/pack.c b/pack.c @@ -13,6 +13,7 @@ #include "open.h" #include "pack.h" #include "stralloc.h" +#include "lock.h" size_t pack_fmt(pack const *p, char *buf) @@ -169,34 +170,47 @@ pack_hasdep(pack const *p, genalloc *packs) } int -pack_step(pack const *p, char const *cmd, char const *log, char const *dir) +pack_step(pack const *p, char const *cmd, char const *log, char const *dir, char const *sub) { char fmt[PACK_FMT]; char const *argv[] = { NULL, NULL, NULL }; stralloc sa; + stralloc sa_tmp; + stralloc sa_log; + char pidfmt[20]; + pid_t pid; + int fd_lock = -1; int ret = -1; - if (dir) - { - stralloc_init(&sa); - if (!stralloc_cats(&sa, dir)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->name)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->ver)) goto err; - if (!stralloc_cat0(&sa)) goto err; - if (!fs_mkdir_r(sa.x, 0640)) goto err; - } + /* lock this operation on this package */ stralloc_zero(&sa); - if (!stralloc_cats(&sa, log)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->name)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->ver)) goto err; - if (!stralloc_cat0(&sa)) goto err; - sa.n--; + if (!pack_dir(p, &sa_lock, dir, "lock")) goto err; + if (!fs_mkdir_r(sa_lock.x)) goto err; + --sa_lock.n; + if (!stralloc_cats(&sa_lock, "/")) goto err; + if (!stralloc_cats(&sa_lock, sub)) goto err; + if (!stralloc_cat0(&sa_lock)) goto err; + + if ((fd = open_write(sa_lock.x)) == -1) goto err; + if (!lock_exclusive(fd)) { close(fd); return -1; } + + /* perform the step in a temporary directory */ + + if ((pid = getpid() == -1)) goto err; + stralloc_init(&sa_tmp); + if (!pack_dir(p, &sa_tmp, dir, "tmp")) goto err; + --sa_tmp.n; + if (!stralloc_cats(&sa_tmp, "/")) goto err; + if (!stralloc_catulong(&sa_tmp, pid)) goto err; + if (!stralloc_cat0(&sa_tmp)) goto err; + + if (!fs_mkdir_r(sa.x, 0640)) goto err; + + stralloc_zero(&sa); + if (!pack_dir(p, &sa, dir, "log")) goto err; if (!fs_mkdir_r(sa.x, 0640)) goto err; + --sa.n; if (!stralloc_cats(&sa, "/")) goto err; if (!stralloc_cats(&sa, cmd + (str_start(cmd, "pack-") ? 5 : 0))) goto err; if (!stralloc_cat0(&sa)) goto err; @@ -463,19 +477,28 @@ err: stralloc_free(&path); } int -pack_isdone(pack const *p, char *dir) +pack_dir(pack const *p, stralloc *sa, char const *dir, char const *sub) +{ + stralloc_zero(sa); + if (!stralloc_cats(sa, dir)) return 0; + if (!stralloc_cats(sa, "/")) return 0; + if (!stralloc_cats(sa, p->name)) return 0; + if (!stralloc_cats(sa, "/")) return 0; + if (!stralloc_cats(sa, p->ver)) return 0; + if (!stralloc_cats(sa, "/")) return 0; + if (!stralloc_cats(sa, sub)) return 0; + if (!stralloc_cat0(sa)) return 0; + return 1; +} + +int +pack_isdone(pack const *p, char *dir, char *sub) { stralloc sa; int ret = 0; stralloc_init(&sa); - if (!stralloc_cats(&sa, dir)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->name)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->ver)) goto err; - if (!stralloc_cat0(&sa)) goto err; - + if (!pack_dir(p, &sa, dir, sub)) goto err; ret = fs_isdir(sa.x); err: stralloc_free(&sa);