diff options
Diffstat (limited to 'src/libs6rc')
-rw-r--r-- | src/libs6rc/s6rc_servicedir_manage.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/src/libs6rc/s6rc_servicedir_manage.c b/src/libs6rc/s6rc_servicedir_manage.c index 529067b..218c0af 100644 --- a/src/libs6rc/s6rc_servicedir_manage.c +++ b/src/libs6rc/s6rc_servicedir_manage.c @@ -48,6 +48,7 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st if (d->d_name[0] == '.') continue ; { size_t len = strlen(d->d_name) ; + int fdlock ; int r ; uint16_t id ; char srcfn[livelen + 20 + len] ; @@ -55,25 +56,29 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st memcpy(srcfn, dirfn, livelen + 12) ; srcfn[livelen + 12] = '/' ; memcpy(srcfn + livelen + 13, d->d_name, len + 1) ; + fdlock = s6_svc_lock_take(srcfn) ; + if (fdlock < 0) goto err ; r = s6_svc_ok(srcfn) ; - if (r < 0) { e = errno ; goto err ; } + if (r < 0) goto errinloop ; if (!r) { memcpy(srcfn + livelen + 13 + len, "/down", 6) ; - if (!touch(srcfn)) { e = errno ; goto err ; } + if (!touch(srcfn)) goto errinloop ; memcpy(srcfn + livelen + 14 + len, "event", 6) ; - if (!ftrigw_fifodir_make(srcfn, gid, 0)) { e = errno ; goto err ; } + if (!ftrigw_fifodir_make(srcfn, gid, 0)) goto errinloop ; id = ftrigr_subscribe(&a, srcfn, "s", 0, deadline, stamp) ; - if (!id) { e = errno ; goto err ; } - if (!genalloc_append(uint16_t, &ids, &id)) { e = errno ; goto err ; } + if (!id) goto errinloop ; + s6_svc_lock_release(fdlock) ; + if (!genalloc_append(uint16_t, &ids, &id)) goto err ; srcfn[livelen + 13 + len] = 0 ; } + else s6_svc_lock_release(fdlock) ; memcpy(dstfn, live, livelen) ; memcpy(dstfn + livelen, "/scandir/", 9) ; memcpy(dstfn + livelen + 9, d->d_name, len + 1) ; if (symlink(srcfn, dstfn) < 0) { - if (!r || errno != EEXIST) { e = errno ; goto err ; } + if (!r || errno != EEXIST) goto err ; } else if (!r) { @@ -81,12 +86,17 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st { e = errno ; s6rc_servicedir_unsupervise(live, d->d_name, 0) ; - goto err ; + goto errn ; } } + continue ; + errinloop: + e = errno ; + s6_svc_lock_release(fdlock) ; + goto errn ; } } - if (errno) { e = errno ; goto err ; } + if (errno) goto err ; dir_close(dir) ; { char scanfn[livelen + 9] ; @@ -94,10 +104,10 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st memcpy(scanfn, live, livelen) ; memcpy(scanfn + livelen, "/scandir", 9) ; r = s6_svc_writectl(scanfn, S6_SVSCAN_CTLDIR, "a", 1) ; - if (r < 0) { e = errno ; goto closederr ; } + if (r < 0) goto closederr ; if (!r) ok = 3 ; else if (ftrigr_wait_and(&a, genalloc_s(uint16_t, &ids), genalloc_len(uint16_t, &ids), deadline, stamp) < 0) - { e = errno ; goto closederr ; } + goto closederr ; } ftrigr_end(&a) ; @@ -106,8 +116,13 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st return ok ; err: + e = errno ; + errn: dir_close(dir) ; + goto closederrn ; closederr: + e = errno ; + closederrn: ftrigr_end(&a) ; genalloc_free(uint16_t, &ids) ; rollback(live, newnames.s, newnames.len) ; |