diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2015-08-16 20:42:56 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2015-08-16 20:42:56 +0000 |
commit | 3f6b6d787b4271e84315c46511db5f5778f6ee5d (patch) | |
tree | cc1c02da1baa1878eedcce143f7a34217c45544e /src | |
parent | 983061db31e02d62359dd8a0cb1e9f125950cfdb (diff) | |
download | s6-rc-3f6b6d787b4271e84315c46511db5f5778f6ee5d.tar.xz |
Safer version of pipelines, with an auto-refilling fdholder
Diffstat (limited to 'src')
-rw-r--r-- | src/libs6rc/s6rc_db_check_pipelines.c | 2 | ||||
-rw-r--r-- | src/s6-rc/deps-exe/s6-rc-fdholder-filler | 4 | ||||
-rw-r--r-- | src/s6-rc/deps-exe/s6-rc-update | 1 | ||||
-rw-r--r-- | src/s6-rc/s6-rc-compile.c | 213 | ||||
-rw-r--r-- | src/s6-rc/s6-rc-db.c | 6 | ||||
-rw-r--r-- | src/s6-rc/s6-rc-fdholder-filler.c | 77 |
6 files changed, 180 insertions, 123 deletions
diff --git a/src/libs6rc/s6rc_db_check_pipelines.c b/src/libs6rc/s6rc_db_check_pipelines.c index 19dc141..d2547fc 100644 --- a/src/libs6rc/s6rc_db_check_pipelines.c +++ b/src/libs6rc/s6rc_db_check_pipelines.c @@ -31,7 +31,7 @@ int s6rc_db_check_pipelines (s6rc_db_t const *db, diuint32 *problem) j = i ; for (;;) { - register unsigned int k = db->services[j].x.longrun.pipeline[1] ; + register uint32 k = db->services[j].x.longrun.pipeline[1] ; if (k >= db->nlong) break ; if (k == i || bitarray_peek(black, k)) { diff --git a/src/s6-rc/deps-exe/s6-rc-fdholder-filler b/src/s6-rc/deps-exe/s6-rc-fdholder-filler new file mode 100644 index 0000000..ccb415f --- /dev/null +++ b/src/s6-rc/deps-exe/s6-rc-fdholder-filler @@ -0,0 +1,4 @@ +-ls6 +-lskarnet +${TAINNOW_LIB} +${SOCKET_LIB} diff --git a/src/s6-rc/deps-exe/s6-rc-update b/src/s6-rc/deps-exe/s6-rc-update index ba32165..bebbac1 100644 --- a/src/s6-rc/deps-exe/s6-rc-update +++ b/src/s6-rc/deps-exe/s6-rc-update @@ -3,3 +3,4 @@ ${LIBS6RC} -lexecline -lskarnet ${TAINNOW_LIB} +${SOCKET_LIB} diff --git a/src/s6-rc/s6-rc-compile.c b/src/s6-rc/s6-rc-compile.c index 57edec9..65b9857 100644 --- a/src/s6-rc/s6-rc-compile.c +++ b/src/s6-rc/s6-rc-compile.c @@ -25,6 +25,7 @@ #include <execline/config.h> #include <execline/execline.h> #include <s6/config.h> +#include <s6-rc/config.h> #include <s6-rc/s6rc.h> #define USAGE "s6-rc-compile [ -v verbosity ] [ -u okuid,okuid... ] [ -g okgid,okgid... ] [ -h fdholder_user ] destdir sources..." @@ -42,6 +43,21 @@ S6_EXTBINPREFIX "s6-ipcserverd -1 --\n" \ S6_EXTBINPREFIX "s6-ipcserver-access -v0 -E -l0 -i data/rules --\n" \ S6_EXTBINPREFIX "s6-sudod -t 2000 --\n" +#define S6RC_FDHOLDER_RUNSCRIPT \ +"#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n" \ +EXECLINE_EXTBINPREFIX "pipeline -dw --\n{\n " \ +EXECLINE_EXTBINPREFIX "if -n --\n {\n " \ +EXECLINE_EXTBINPREFIX "forstdin -x 1 -- i\n " \ +EXECLINE_EXTBINPREFIX "exit 1\n }\n " \ +EXECLINE_EXTBINPREFIX "if -nt --\n {\n " \ +EXECLINE_EXTBINPREFIX "redirfd -r 0 data/pipes-to-create\n " \ +EXECLINE_EXTBINPREFIX "withstdinas PIPES\n " \ +EXECLINE_EXTBINPREFIX "import -u -sd\"\n\" -- PIPES\n " \ +S6_EXTBINPREFIX "s6-ipcclient -l0 -- s\n " \ +S6RC_BINPREFIX "s6-rc-fdholder-filler -1 -- $PIPES\n }\n " \ +S6_EXTBINPREFIX "s6-svc -t .\n}\n" \ +S6_EXTBINPREFIX "s6-fdholder-daemon -1 -i data/rules -- s\n" + static unsigned int verbosity = 1 ; static stralloc keep = STRALLOC_ZERO ; static stralloc data = STRALLOC_ZERO ; @@ -255,82 +271,6 @@ static unsigned int add_internal_longrun (before_t *be, char const *name) return pos ; } -static unsigned int add_internal_oneshot (before_t *be, char const *name, char const *ups, unsigned int upn, char const *downs, unsigned int downn) -{ - unsigned int pos ; - oneshot_t service = - { - .common = - { - .ndeps = 2, - .depindex = genalloc_len(unsigned int, &be->indices), - .annotation_flags = 0, - .timeout = { 0, 0 } - }, - .argvindex = { keep.len, keep.len + downn } - } ; - service.argc[0] = byte_count(downs, downn, '\0') ; - service.argc[1] = byte_count(ups, upn, '\0') ; - if (!genalloc_catb(unsigned int, &be->indices, be->specialdeps, 2) - || !stralloc_catb(&keep, downs, downn) - || !stralloc_catb(&keep, ups, upn)) dienomem() ; - add_name_nocheck(be, S6RC_INTERNALS, name, SVTYPE_ONESHOT, &pos, &service.common.kname) ; - if (!genalloc_append(oneshot_t, &be->oneshots, &service)) dienomem() ; - be->nargvs += service.argc[0] + service.argc[1] + 2 ; - return pos ; -} - -static void add_word (char const *word) -{ - if (!stralloc_cats(&satmp, word) || !stralloc_0(&satmp)) dienomem() ; -} - -static unsigned int add_storepipe (before_t *be, char const *name) -{ - unsigned int pos, sep, base = satmp.len ; - unsigned int namelen = str_len(name) ; - char svname[16 + namelen] ; - byte_copy(svname, 15, "s6rc-storepipe-") ; - byte_copy(svname + 15, namelen + 1, name) ; - - add_word(EXECLINE_EXTBINPREFIX "piperw") ; - add_word("0") ; - add_word("1") ; - add_word(EXECLINE_EXTBINPREFIX "if") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING S6_EXTBINPREFIX "s6-fdholder-store") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING "../s6rc-fdholder/s") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING "pipe:s6rc-r-") ; satmp.len-- ; add_word(name) ; - add_word(EXECLINE_BLOCK_END_STRING) ; - add_word(EXECLINE_EXTBINPREFIX "if") ; - add_word("-nt") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING S6_EXTBINPREFIX "s6-fdholder-store") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING "-d1") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING "../s6rc-fdholder/s") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING "pipe:s6rc-w-") ; satmp.len-- ; add_word(name) ; - add_word(EXECLINE_BLOCK_END_STRING) ; - add_word(EXECLINE_EXTBINPREFIX "exit") ; - add_word("1") ; - - sep = satmp.len ; - - add_word(EXECLINE_EXTBINPREFIX "foreground") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING S6_EXTBINPREFIX "s6-fdholder-delete") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING "../s6rc-fdholder/s") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING "pipe:s6rc-w-") ; satmp.len-- ; add_word(name) ; - add_word(EXECLINE_BLOCK_END_STRING) ; - add_word(EXECLINE_EXTBINPREFIX "foreground") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING S6_EXTBINPREFIX "s6-fdholder-delete") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING "../s6rc-fdholder/s") ; - add_word(EXECLINE_BLOCK_QUOTE_STRING "pipe:s6rc-r-") ; satmp.len-- ; add_word(name) ; - add_word(EXECLINE_BLOCK_END_STRING) ; - add_word(EXECLINE_EXTBINPREFIX "exit") ; - add_word("0") ; - - pos = add_internal_oneshot(be, svname, satmp.s + base, sep - base, satmp.s + sep, satmp.len - sep) ; - satmp.len = base ; - return pos ; -} - static int uint_uniq (unsigned int const *list, unsigned int n, unsigned int pos) { while (n--) if (pos == list[n]) return 0 ; @@ -498,16 +438,8 @@ static inline void add_longrun (before_t *be, int dirfd, char const *srcdir, cha if (n != 1) strerr_dief5x(1, srcdir, "/", name, "/producer-for", " should only contain one service name") ; service.pipeline[1] = genalloc_s(unsigned int, &be->indices)[relatedindex] ; - { - unsigned int dummy ; - unsigned int namelen = str_len(data.s + service.pipeline[1]) ; - char svname[16 + namelen] ; - byte_copy(svname, 15, "s6rc-storepipe-") ; - byte_copy(svname + 15, namelen + 1, data.s + service.pipeline[1]) ; - add_name_nocheck(be, srcdir, svname, SVTYPE_UNDEFINED, &n, &dummy) ; - if (!genalloc_append(unsigned int, &be->indices, &n)) dienomem() ; - service.common.ndeps += 2 ; - } + if (!genalloc_append(unsigned int, &be->indices, &be->specialdeps[1])) dienomem() ; + service.common.ndeps += 2 ; if (verbosity >= 3) strerr_warni3x(name, " is a producer for ", data.s + service.pipeline[1]) ; fd = 1 ; @@ -517,12 +449,15 @@ static inline void add_longrun (before_t *be, int dirfd, char const *srcdir, cha if (n != 1) strerr_dief5x(1, srcdir, "/", name, "/consumer-for", " should only contain one service name") ; service.pipeline[0] = genalloc_s(unsigned int, &be->indices)[relatedindex] ; + genalloc_setlen(unsigned int, &be->indices, relatedindex) ; + if (!fd) + { + genalloc_append(unsigned int, &be->indices, &be->specialdeps[1]) ; + service.common.ndeps++ ; + } + else fd = 0 ; if (verbosity >= 3) strerr_warni3x(name, " is a consumer for ", data.s + service.pipeline[0]) ; - n = add_storepipe(be, name) ; - genalloc_s(unsigned int, &be->indices)[relatedindex] = n ; - service.common.ndeps++ ; - fd = 0 ; } if (fd && add_namelist(be, dirfd, srcdir, name, "pipeline-name", &relatedindex, &n)) { @@ -626,16 +561,7 @@ static inline void add_pipeline_bundles (before_t *be) strerr_dief5x(1, "longrun service ", keep.s + longruns[j].common.kname, " declares a consumer ", data.s + longruns[j].pipeline[1], " that is not a longrun service") ; if (!genalloc_append(unsigned int, &be->indices, &info->pos)) dienomem() ; j = info->i ; - { - unsigned int namelen = str_len(data.s + info->pos) ; - char svname[16 + namelen] ; - byte_copy(svname, 15, "s6rc-storepipe-") ; - byte_copy(svname + 15, namelen + 1, data.s + info->pos) ; - avltree_search(&names_map, svname, &id) ; - info = genalloc_s(nameinfo_t, &nameinfo) + id ; - if (!genalloc_append(unsigned int, &be->indices, &info->pos)) dienomem() ; - } - bundle.n += 2 ; + bundle.n++ ; } if (!genalloc_append(bundle_t, &be->bundles, &bundle)) dienomem() ; } @@ -750,7 +676,7 @@ static void resolve_deps (common_t const *me, unsigned int nlong, unsigned int n { char fmt[UINT_FMT] ; fmt[uint_fmt(fmt, nlong + p->i)] = 0 ; - strerr_warnt7x("atomic ", keep.s + me->kname, " depends on oneshot ", data.s + p->pos, " (", fmt, ")") ; + strerr_warnt6x(keep.s + me->kname, " depends on oneshot ", data.s + p->pos, " (", fmt, ")") ; } break ; case SVTYPE_LONGRUN : @@ -759,7 +685,7 @@ static void resolve_deps (common_t const *me, unsigned int nlong, unsigned int n { char fmt[UINT_FMT] ; fmt[uint_fmt(fmt, p->i)] = 0 ; - strerr_warnt7x("atomic ", keep.s + me->kname, " depends on longrun ", data.s + p->pos, " (", fmt, ")") ; + strerr_warnt6x(keep.s + me->kname, " depends on longrun ", data.s + p->pos, " (", fmt, ")") ; } break ; case SVTYPE_BUNDLE : @@ -768,7 +694,7 @@ static void resolve_deps (common_t const *me, unsigned int nlong, unsigned int n { char fmt[UINT_FMT] ; fmt[uint_fmt(fmt, nlong + p->i)] = 0 ; - strerr_warnt4x("atomic ", keep.s + me->kname, " depends on bundle ", data.s + p->pos) ; + strerr_warnt3x(keep.s + me->kname, " depends on bundle ", data.s + p->pos) ; } break ; default : @@ -884,14 +810,14 @@ static inline void flatlist_services (s6rc_db_t *db, unsigned char const *sarray if (verbosity >= 3) strerr_warni1x("checking database correctness") ; if (s6rc_db_check_depcycles(db, 1, &problem)) - strerr_dief4x(1, "cyclic service dependency involving", db->string + db->services[problem.left].name, " and ", db->string + db->services[problem.right].name) ; + strerr_dief5x(1, "cyclic service dependency", " reached from ", db->string + db->services[problem.left].name, " and involving ", db->string + db->services[problem.right].name) ; r = s6rc_db_check_pipelines(db, &problem) ; if (r) { if (r == 1) - strerr_dief4x(1, "cyclic longrun pipeline involving", db->string + db->services[problem.left].name, " and ", db->string + db->services[problem.right].name) ; + strerr_dief5x(1, "cyclic longrun pipeline", " reached from ", db->string + db->services[problem.left].name, " and involving ", db->string + db->services[problem.right].name) ; else - strerr_dief4x(1, "longrun pipeline collision involving", db->string + db->services[problem.left].name, " and ", db->string + db->services[problem.right].name) ; + strerr_dief5x(1, "longrun pipeline collision", " reached from ", db->string + db->services[problem.left].name, " and involving ", db->string + db->services[problem.right].name) ; } } @@ -986,16 +912,18 @@ static inline void write_sizes (char const *compiled, s6rc_db_t const *db) auto_file(compiled, "n", pack, 20) ; } -static void make_skel (char const *compiled, char const *name, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn) +static void make_skel (char const *compiled, char const *name, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn, unsigned int notif) { unsigned int namelen = str_len(name) ; - unsigned int i = uidn ; + char fmt[UINT_FMT] ; + unsigned int i = uint_fmt(fmt, notif) ; + fmt[i++] = '\n' ; char fn[UINT64_FMT + namelen + 35] ; byte_copy(fn, 12, "servicedirs/") ; byte_copy(fn + 12, namelen + 1, name) ; auto_dir(compiled, fn) ; byte_copy(fn + 12 + namelen, 17, "/notification-fd") ; - auto_file(compiled, fn, "3\n", 2) ; + auto_file(compiled, fn, fmt, i) ; byte_copy(fn + 13 + namelen, 5, "data") ; auto_dir(compiled, fn) ; byte_copy(fn + 17 + namelen, 7, "/rules") ; @@ -1008,6 +936,7 @@ static void make_skel (char const *compiled, char const *name, uint64 const *uid byte_copy(fn + 23 + namelen, 5, "/uid") ; auto_dir(compiled, fn) ; fn[27 + namelen] = '/' ; + i = uidn ; while (i--) { unsigned int len = uint64_fmt(fn + 28 + namelen, uids[i]) ; @@ -1029,15 +958,42 @@ static void make_skel (char const *compiled, char const *name, uint64 const *uid static inline void write_oneshot_runner (char const *compiled, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn) { - make_skel(compiled, S6RC_ONESHOT_RUNNER, uids, uidn, gids, gidn) ; + make_skel(compiled, S6RC_ONESHOT_RUNNER, uids, uidn, gids, gidn, 3) ; auto_file(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/run", S6RC_ONESHOT_RUNNER_RUNSCRIPT, sizeof(S6RC_ONESHOT_RUNNER_RUNSCRIPT) - 1) ; auto_rights(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/run", 0755) ; } -static inline void write_fdholder (char const *compiled, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn, char const *fdhuser) +static inline int write_pipelines (stralloc *sa, s6rc_db_t const *db) +{ + uint32 i = db->nlong ; + unsigned char black[bitarray_div8(db->nlong)] ; + byte_zero(black, bitarray_div8(db->nlong)) ; + while (i--) if (!bitarray_peek(black, i)) + { + uint32 j = i ; + for (;;) + { + register uint32 k = db->services[j].x.longrun.pipeline[0] ; + if (k >= db->nlong) break ; + j = k ; + } + for (;;) + { + register uint32 k = db->services[j].x.longrun.pipeline[1] ; + bitarray_set(black, j) ; + if (k >= db->nlong) break ; + if (!string_quote(sa, db->string + db->services[k].name, str_len(db->string + db->services[k].name)) + || !stralloc_catb(sa, " ", 1)) return 0 ; + j = k ; + } + } + return 1 ; +} + +static inline void write_fdholder (char const *compiled, s6rc_db_t const *db, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn, char const *fdhuser) { unsigned int base = satmp.len ; - make_skel(compiled, S6RC_FDHOLDER, uids, uidn, gids, gidn) ; + make_skel(compiled, S6RC_FDHOLDER, uids, uidn, gids, gidn, 1) ; { char fn[62 + S6RC_FDHOLDER_LEN + UINT64_FMT] = "servicedirs/" S6RC_FDHOLDER "/data/rules/uid/" ; char fmt[7 + UINT64_FMT] = "../uid/" ; @@ -1074,9 +1030,17 @@ static inline void write_fdholder (char const *compiled, uint64 const *uids, uns } if (!stralloc_cats(&satmp, - "#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n" \ - EXECLINE_EXTBINPREFIX "fdmove -c 2 1\n" \ - EXECLINE_EXTBINPREFIX "fdmove 1 3\n")) dienomem() ; + "#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n" + EXECLINE_EXTBINPREFIX "pipeline -dw --\n{\n " + EXECLINE_EXTBINPREFIX "if -n --\n {\n " + EXECLINE_EXTBINPREFIX "forstdin -x 1 -- i\n " + EXECLINE_EXTBINPREFIX "exit 1\n }\n " + EXECLINE_EXTBINPREFIX "if -nt --\n {\n " + S6_EXTBINPREFIX "s6-ipcclient -l0 -- s\n " + S6RC_BINPREFIX "s6-rc-fdholder-filler -1 -- ") + || !write_pipelines(&satmp, db) + || !stralloc_cats(&satmp, "\n }\n " + S6_EXTBINPREFIX "s6-svc -t .\n}\n")) dienomem() ; if (fdhuser) { if (!stralloc_cats(&satmp, S6_EXTBINPREFIX "s6-envuidgid -i -- ") @@ -1094,10 +1058,10 @@ static inline void write_fdholder (char const *compiled, uint64 const *uids, uns auto_rights(compiled, "servicedirs/" S6RC_FDHOLDER "/run", 0755) ; } -static inline void write_specials (char const *compiled, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn, char const *fdhuser) +static inline void write_specials (char const *compiled, s6rc_db_t const *db, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn, char const *fdhuser) { write_oneshot_runner(compiled, uids, uidn, gids, gidn) ; - write_fdholder(compiled, uids, uidn, gids, gidn, fdhuser) ; + write_fdholder(compiled, db, uids, uidn, gids, gidn, fdhuser) ; } static inline void write_resolve (char const *compiled, s6rc_db_t const *db, bundle_t const *bundles, unsigned int nbundles, uint32 const *bdeps) @@ -1427,7 +1391,18 @@ static inline void write_db (char const *compiled, s6rc_db_t const *db) strerr_diefu2sys(111, "write to ", dbfn) ; } -static inline void write_compiled (char const *compiled, s6rc_db_t const *db, char const *const *srcdirs, bundle_t const *bundles, unsigned int nbundles, uint32 const *bdeps, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn, char const *fdhuser) +static inline void write_compiled ( + char const *compiled, + s6rc_db_t const *db, + char const *const *srcdirs, + bundle_t const *bundles, + unsigned int nbundles, + uint32 const *bdeps, + uint64 const *uids, + unsigned int uidn, + gid_t const *gids, + unsigned int gidn, + char const *fdhuser) { if (verbosity >= 2) strerr_warni2x("writing compiled information to ", compiled) ; init_compiled(compiled) ; @@ -1435,7 +1410,7 @@ static inline void write_compiled (char const *compiled, s6rc_db_t const *db, ch write_resolve(compiled, db, bundles, nbundles, bdeps) ; stralloc_free(&data) ; write_db(compiled, db) ; - write_specials(compiled, uids, uidn, gids, gidn, fdhuser) ; + write_specials(compiled, db, uids, uidn, gids, gidn, fdhuser) ; write_servicedirs(compiled, db, srcdirs) ; } diff --git a/src/s6-rc/s6-rc-db.c b/src/s6-rc/s6-rc-db.c index 97f0956..a89b1e4 100644 --- a/src/s6-rc/s6-rc-db.c +++ b/src/s6-rc/s6-rc-db.c @@ -440,14 +440,14 @@ int main (int argc, char const *const *argv) if (s6rc_db_check_revdeps(&dbblob)) strerr_dief3x(4, "invalid service database in ", compiled, ": direct and reverse dependencies are mismatched") ; if (s6rc_db_check_depcycles(&dbblob, 1, &problem)) - strerr_dief8x(4, "invalid service database in ", compiled, ": dependency ", "cycle", " involving ", stringblob + serviceblob[problem.left].name, " and ", stringblob + serviceblob[problem.right].name) ; + strerr_dief8x(4, "invalid service database in ", compiled, ": dependency ", "cycle", " reached from ", stringblob + serviceblob[problem.left].name, " and involving ", stringblob + serviceblob[problem.right].name) ; r = s6rc_db_check_pipelines(&dbblob, &problem) ; if (r) { if (r == 1) - strerr_dief8x(4, "invalid service database in ", compiled, ": pipeline ", "cycle", " involving ", stringblob + serviceblob[problem.left].name, " and ", stringblob + serviceblob[problem.right].name) ; + strerr_dief8x(4, "invalid service database in ", compiled, ": pipeline ", "cycle", " reached from ", stringblob + serviceblob[problem.left].name, " and involving ", stringblob + serviceblob[problem.right].name) ; else - strerr_dief8x(4, "invalid service database in ", compiled, ": pipeline ", "collision", " involving ", stringblob + serviceblob[problem.left].name, " and ", stringblob + serviceblob[problem.right].name) ; + strerr_dief8x(4, "invalid service database in ", compiled, ": pipeline ", "collision", " reached from ", stringblob + serviceblob[problem.left].name, " and involving ", stringblob + serviceblob[problem.right].name) ; } break ; } diff --git a/src/s6-rc/s6-rc-fdholder-filler.c b/src/s6-rc/s6-rc-fdholder-filler.c new file mode 100644 index 0000000..06afdee --- /dev/null +++ b/src/s6-rc/s6-rc-fdholder-filler.c @@ -0,0 +1,77 @@ +/* ISC license. */ + +#include <unistd.h> +#include <errno.h> +#include <skalibs/uint.h> +#include <skalibs/bytestr.h> +#include <skalibs/strerr2.h> +#include <skalibs/sgetopt.h> +#include <skalibs/tai.h> +#include <s6/s6-fdholder.h> + +#define USAGE "s6-rc-fdholder-filler [ -1 ] [ -t timeout ] longrunnames..." +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + s6_fdholder_t a = S6_FDHOLDER_ZERO ; + tain_t deadline ; + int notif = 0 ; + PROG = "s6-rc-fdholder-filler" ; + { + unsigned int t = 0 ; + subgetopt_t l = SUBGETOPT_ZERO ; + for (;;) + { + register int opt = subgetopt_r(argc, argv, "1t:", &l) ; + if (opt == -1) break ; + switch (opt) + { + case '1': notif = 1 ; break ; + case 't': if (!uint0_scan(l.arg, &t)) dieusage() ; break ; + default : strerr_dieusage(100, USAGE) ; + } + } + argc -= l.ind ; argv += l.ind ; + if (t) tain_from_millisecs(&deadline, t) ; + else deadline = tain_infinite_relative ; + } + + s6_fdholder_init(&a, 6) ; + tain_now_g() ; + tain_add_g(&deadline, &deadline) ; + if (argc) + { + tain_t offset = { .sec = TAI_ZERO } ; + int p[2] ; + unsigned int n = argc ; + unsigned int i = 0 ; + s6_fdholder_fd_t dump[n<<1] ; + for (; i < n ; i++) + { + unsigned int len = str_len(argv[i]) ; + if (len + 12 > S6_FDHOLDER_ID_SIZE) + { + errno = ENAMETOOLONG ; + strerr_diefu2sys(111, "create identifier for ", argv[i]) ; + } + if (pipe(p) < 0) + strerr_diefu1sys(111, "create pipe") ; + dump[i<<1].fd = p[0] ; + tain_add_g(&dump[i<<1].limit, &tain_infinite_relative) ; + offset.nano = i << 1 ; + tain_add(&dump[i<<1].limit, &dump[i<<1].limit, &offset) ; + byte_copy(dump[i<<1].id, 12, "pipe:s6rc-r-") ; + byte_copy(dump[i<<1].id + 12, len + 1, argv[i]) ; + dump[(i<<1)+1].fd = p[1] ; + offset.nano = 1 ; + tain_add(&dump[(i<<1)+1].limit, &dump[i<<1].limit, &offset) ; + byte_copy(dump[(i<<1)+1].id, 12 + len, dump[i<<1].id) ; + dump[(i<<1)+1].id[10] = 'w' ; + } + if (!s6_fdholder_setdump_g(&a, dump, n << 1, &deadline)) + strerr_diefu1sys(111, "transfer pipes") ; + } + if (notif) write(1, "\n", 1) ; + return 0 ; +} |