summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/conn-tools/deps-exe/s6-ipcserverd1
-rw-r--r--src/conn-tools/s6-ipcserverd.c31
-rw-r--r--src/daemontools-extras/deps-exe/s6-setlock4
-rw-r--r--src/daemontools-extras/s6-setlock.c87
-rw-r--r--src/libs6/deps-lib/s610
-rw-r--r--src/libs6/deps-lib/s6lockd1
-rw-r--r--src/libs6/s6lock_acquire.c41
-rw-r--r--src/libs6/s6lock_check.c24
-rw-r--r--src/libs6/s6lock_end.c15
-rw-r--r--src/libs6/s6lock_release.c23
-rw-r--r--src/libs6/s6lock_start.c9
-rw-r--r--src/libs6/s6lock_startf.c13
-rw-r--r--src/libs6/s6lock_update.c37
-rw-r--r--src/libs6/s6lock_wait_and.c25
-rw-r--r--src/libs6/s6lock_wait_or.c32
-rw-r--r--src/libs6/s6lock_zero.c5
-rw-r--r--src/libs6/s6lockd-helper.c22
-rw-r--r--src/libs6/s6lockd.c318
-rw-r--r--src/libs6/s6lockd_openandlock.c35
19 files changed, 61 insertions, 672 deletions
diff --git a/src/conn-tools/deps-exe/s6-ipcserverd b/src/conn-tools/deps-exe/s6-ipcserverd
index bfcb622..19869b2 100644
--- a/src/conn-tools/deps-exe/s6-ipcserverd
+++ b/src/conn-tools/deps-exe/s6-ipcserverd
@@ -1,3 +1,2 @@
-${LIBS6}
-lskarnet
${SOCKET_LIB}
diff --git a/src/conn-tools/s6-ipcserverd.c b/src/conn-tools/s6-ipcserverd.c
index 2987763..3190985 100644
--- a/src/conn-tools/s6-ipcserverd.c
+++ b/src/conn-tools/s6-ipcserverd.c
@@ -20,9 +20,8 @@
#include <skalibs/selfpipe.h>
#include <skalibs/iopause.h>
#include <skalibs/socket.h>
-#include <skalibs/exec.h>
-
-#include <s6/ucspiserver.h>
+#include <skalibs/env.h>
+#include <skalibs/cspawn.h>
#define USAGE "s6-ipcserverd [ -v verbosity ] [ -1 ] [ -P | -p ] [ -c maxconn ] [ -C localmaxconn ] prog..."
@@ -55,9 +54,6 @@ static unsigned int numconn = 0 ;
static uidnum_t *uidnum ;
static unsigned int uidlen = 0 ;
-
- /* Utility functions */
-
static inline void dieusage ()
{
strerr_dieusage(100, USAGE) ;
@@ -68,9 +64,6 @@ static inline void X (void)
strerr_dief1x(101, "internal inconsistency. Please submit a bug-report.") ;
}
-
- /* Lookup primitives */
-
static unsigned int lookup_pid (pid_t pid)
{
unsigned int i = 0 ;
@@ -85,9 +78,6 @@ static inline unsigned int lookup_uid (uid_t uid)
return i ;
}
-
- /* Logging */
-
static inline void log_start (void)
{
strerr_warni1x("starting") ;
@@ -147,9 +137,6 @@ static inline void log_close (pid_t pid, uid_t uid, int w)
strerr_warni6x("end pid ", fmtpid, " uid ", fmtuid, WIFSIGNALED(w) ? " signal " : " exitcode ", fmtw) ;
}
-
- /* Signal handling */
-
static void killthem (int sig)
{
unsigned int i = 0 ;
@@ -227,9 +214,6 @@ static inline void handle_signals (void)
}
}
-
- /* New connection handling */
-
static void new_connection (int s, char const *remotepath, char const *const *argv, char const *const *envp, size_t envlen)
{
uid_t uid = 0 ;
@@ -238,6 +222,12 @@ static void new_connection (int s, char const *remotepath, char const *const *ar
size_t rplen = strlen(remotepath) + 1 ;
pid_t pid ;
unsigned int num, i ;
+ cspawn_fileaction fa[2] =
+ {
+ [0] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = 0, [1] = s } } },
+ [1] = { .type = CSPAWN_FA_COPY, .x = { .fd2 = { [0] = 1, [1] = 0 } } }
+ } ;
+ char const *newenvp[envlen + 6] ;
char fmt[65 + UID_FMT + GID_FMT + UINT_FMT + rplen] ;
if (flaglookup && (getpeereid(s, &uid, &gid) < 0))
@@ -272,8 +262,8 @@ static void new_connection (int s, char const *remotepath, char const *const *ar
fmt[m++] = 0 ;
memcpy(fmt + m, "IPCREMOTEPATH=", 14) ; m += 14 ;
memcpy(fmt + m, remotepath, rplen) ; m += rplen ;
-
- pid = s6_ucspiserver_spawn(s, argv, envp, envlen, fmt, m, 5) ;
+ env_mergen(newenvp, envlen + 6, envp, envlen, fmt, m, 5) ;
+ pid = cspawn(argv[0], argv, newenvp, CSPAWN_FLAGS_SELFPIPE_FINISH, fa, 2) ;
if (!pid)
{
if (verbosity) strerr_warnwu2sys("spawn ", argv[0]) ;
@@ -295,7 +285,6 @@ static void new_connection (int s, char const *remotepath, char const *const *ar
}
}
-
int main (int argc, char const *const *argv)
{
iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .fd = 0, .events = IOPAUSE_READ | IOPAUSE_EXCEPT } } ;
diff --git a/src/daemontools-extras/deps-exe/s6-setlock b/src/daemontools-extras/deps-exe/s6-setlock
index 9bb3918..3dc5bdf 100644
--- a/src/daemontools-extras/deps-exe/s6-setlock
+++ b/src/daemontools-extras/deps-exe/s6-setlock
@@ -1,4 +1,2 @@
-libs6lockd.a.xyzzy
-lskarnet
-${SYSCLOCK_LIB}
-${SPAWN_LIB}
+${TIMER_LIB}
diff --git a/src/daemontools-extras/s6-setlock.c b/src/daemontools-extras/s6-setlock.c
index fea6a11..673caaf 100644
--- a/src/daemontools-extras/s6-setlock.c
+++ b/src/daemontools-extras/s6-setlock.c
@@ -4,30 +4,40 @@
#include <errno.h>
#include <signal.h>
-#include <skalibs/allreadwrite.h>
#include <skalibs/sgetopt.h>
#include <skalibs/strerr.h>
#include <skalibs/types.h>
#include <skalibs/tai.h>
-#include <skalibs/iopause.h>
-#include <skalibs/cspawn.h>
+#include <skalibs/sig.h>
+#include <skalibs/alarm.h>
#include <skalibs/djbunix.h>
#include <skalibs/exec.h>
#include <s6/config.h>
-#include "s6lockd.h"
-#define USAGE "s6-setlock [ -r | -w ] [ -n | -N | -t timeout ] lockfile prog..."
+#define USAGE "s6-setlock [ -r | -w ] [ -n | -N ] [ -t timeout ] [ -d fd ] lockfile prog..."
#define dieusage() strerr_dieusage(100, USAGE)
+static char const *file ;
+
+static void sigalrm_handler (int sig)
+{
+ (void)sig ;
+ strerr_dief3x(1, "lock ", file, ": timed out") ;
+}
+
int main (int argc, char const *const *argv)
{
unsigned int nb = 0, ex = 1 ;
unsigned int timeout = 0 ;
+ int dest = -1 ;
+ int fd ;
+ int r ;
PROG = "s6-setlock" ;
+
for (;;)
{
- int opt = lgetopt(argc, argv, "nNrwt:") ;
+ int opt = lgetopt(argc, argv, "nNrwt:d:") ;
if (opt == -1) break ;
switch (opt)
{
@@ -35,47 +45,50 @@ int main (int argc, char const *const *argv)
case 'N' : nb = 0 ; break ;
case 'r' : ex = 0 ; break ;
case 'w' : ex = 1 ; break ;
- case 't' : if (!uint0_scan(subgetopt_here.arg, &timeout)) dieusage() ; nb = 2 ; break ;
+ case 't' : if (!uint0_scan(subgetopt_here.arg, &timeout)) dieusage() ; break ;
+ case 'd' : { unsigned int u ; if (!uint0_scan(subgetopt_here.arg, &u)) dieusage() ; dest = u ; break ; }
default : dieusage() ;
}
}
argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ;
if (argc < 2) dieusage() ;
+ file = argv[0] ;
- if (nb < 2) s6lockd_openandlock(argv[0], ex, nb) ;
+ if (ex)
+ {
+ fd = open_create(file) ;
+ if (fd == -1) strerr_diefu3sys(111, "open ", file, " for writing") ;
+ }
else
{
- char const *cargv[4] = { "s6lockd-helper", ex ? "w" : "r", argv[0], 0 } ;
- char const *nullenv = { 0 } ;
- iopause_fd x = { .events = IOPAUSE_READ } ;
- tain deadline ;
- int p[2] = { 0, 1 } ;
- pid_t pid ;
- char c ;
- tain_now_set_stopwatch_g() ;
- tain_from_millisecs(&deadline, timeout) ;
- tain_add_g(&deadline, &deadline) ;
- pid = child_spawn2(S6_LIBEXECPREFIX "s6lockd-helper", cargv, &nullenv, p) ;
- if (!pid) strerr_diefu2sys(111, "spawn ", S6_LIBEXECPREFIX "s6lockd-helper") ;
- x.fd = p[0] ;
- for (;;)
+ fd = open_read(file) ;
+ if (fd == -1)
{
- ssize_t rr ;
- int r = iopause_g(&x, 1, &deadline) ;
- if (r < 0) strerr_diefu1sys(111, "iopause") ;
- if (!r)
- {
- kill(pid, SIGTERM) ;
- errno = ETIMEDOUT ;
- strerr_diefu1sys(1, "acquire lock") ;
- }
- rr = sanitize_read(fd_read(p[0], &c, 1)) ;
- if (rr < 0) strerr_diefu1sys(111, "read ack from helper") ;
- if (rr) break ;
+ if (errno != ENOENT) strerr_diefu3sys(111, "open ", file, " for reading") ;
+ fd = open_create(file) ;
+ if (fd == -1) strerr_diefu2sys(111, "create ", file) ;
+ fd_close(fd) ;
+ fd = open_read(file) ;
+ if (fd == -1) strerr_diefu3sys(111, "open ", file, " for reading") ;
}
- if (c != '!') strerr_dief1x(111, "helper sent garbage ack") ;
- fd_close(p[0]) ;
- if (uncoe(p[1]) < 0) strerr_diefu1sys(111, "uncoe fd to helper") ;
}
+
+ if (timeout)
+ {
+ tain tto ;
+ tain_from_millisecs(&tto, timeout) ;
+ if (!sig_catch(SIGALRM, &sigalrm_handler))
+ strerr_diefu1sys(111, "set SIGALRM handler") ;
+ if (!alarm_timeout(&tto))
+ strerr_diefu1sys(111, "set timer") ;
+ }
+ r = fd_lock(fd, ex, nb) ;
+ if (timeout) alarm_disable() ;
+
+ if (!r) errno = EBUSY ;
+ if (r < 1) strerr_diefu2sys(1, "lock ", file) ;
+
+ if (dest >= 0 && fd_move(dest, fd) == -1)
+ strerr_diefu1sys(111, "move lock descriptor") ;
xexec(argv+1) ;
}
diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6
index 13b9a83..59999be 100644
--- a/src/libs6/deps-lib/s6
+++ b/src/libs6/deps-lib/s6
@@ -42,16 +42,6 @@ s6_svstatus_pack.o
s6_svstatus_read.o
s6_svstatus_unpack.o
s6_svstatus_write.o
-s6lock_acquire.o
-s6lock_check.o
-s6lock_end.o
-s6lock_release.o
-s6lock_start.o
-s6lock_startf.o
-s6lock_update.o
-s6lock_wait_and.o
-s6lock_wait_or.o
-s6lock_zero.o
s6_fdholder_delete.o
s6_fdholder_delete_async.o
s6_fdholder_end.o
diff --git a/src/libs6/deps-lib/s6lockd b/src/libs6/deps-lib/s6lockd
deleted file mode 100644
index 22cea80..0000000
--- a/src/libs6/deps-lib/s6lockd
+++ /dev/null
@@ -1 +0,0 @@
-s6lockd_openandlock.o
diff --git a/src/libs6/s6lock_acquire.c b/src/libs6/s6lock_acquire.c
deleted file mode 100644
index 890f892..0000000
--- a/src/libs6/s6lock_acquire.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* ISC license. */
-
-#include <sys/uio.h>
-#include <string.h>
-#include <stdint.h>
-#include <errno.h>
-#include <skalibs/uint16.h>
-#include <skalibs/uint32.h>
-#include <skalibs/tai.h>
-#include <skalibs/gensetdyn.h>
-#include <skalibs/textclient.h>
-#include <s6/lock.h>
-
-int s6lock_acquire (s6lock_t *a, uint16_t *u, char const *path, uint32_t options, tain const *limit, tain const *deadline, tain *stamp)
-{
- size_t pathlen = strlen(path) ;
- char tmp[23] = "--<" ;
- struct iovec v[2] = { { .iov_base = tmp, .iov_len = 23 }, { .iov_base = (char *)path, .iov_len = pathlen + 1 } } ;
- uint32_t i ;
- if (pathlen > UINT32_MAX) return (errno = ENAMETOOLONG, 0) ;
- if (!gensetdyn_new(&a->data, &i)) return 0 ;
- if (i > UINT16_MAX)
- {
- gensetdyn_delete(&a->data, i) ;
- return (errno = EMFILE, 0) ;
- }
- uint16_pack_big(tmp, (uint16_t)i) ;
- uint32_pack_big(tmp+3, options) ;
- tain_pack(tmp+7, limit) ;
- uint32_pack_big(tmp+19, (uint32_t)pathlen) ;
- if (!textclient_commandv(&a->connection, v, 2, deadline, stamp))
- {
- int e = errno ;
- gensetdyn_delete(&a->data, i) ;
- errno = e ;
- return 0 ;
- }
- *GENSETDYN_P(unsigned char, &a->data, i) = EAGAIN ;
- *u = i ;
- return 1 ;
-}
diff --git a/src/libs6/s6lock_check.c b/src/libs6/s6lock_check.c
deleted file mode 100644
index 0602d40..0000000
--- a/src/libs6/s6lock_check.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* ISC license. */
-
-#include <errno.h>
-#include <skalibs/error.h>
-#include <skalibs/gensetdyn.h>
-#include <s6/lock.h>
-
-int s6lock_check (s6lock_t *a, uint16_t id)
-{
- unsigned char *p = GENSETDYN_P(unsigned char, &a->data, id) ;
- switch (*p)
- {
- case EBUSY : return 1 ;
- case EINVAL : return (errno = EINVAL, -1) ;
- default :
- {
- if (error_isagain(*p)) return 0 ;
- errno = *p ;
- *p = EINVAL ;
- gensetdyn_delete(&a->data, id) ;
- return -1 ;
- }
- }
-}
diff --git a/src/libs6/s6lock_end.c b/src/libs6/s6lock_end.c
deleted file mode 100644
index 8611289..0000000
--- a/src/libs6/s6lock_end.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/* ISC license. */
-
-#include <stdint.h>
-#include <skalibs/genalloc.h>
-#include <skalibs/gensetdyn.h>
-#include <skalibs/textclient.h>
-#include <s6/lock.h>
-
-void s6lock_end (s6lock_t *a)
-{
- gensetdyn_free(&a->data) ;
- genalloc_free(uint16_t, &a->list) ;
- textclient_end(&a->connection) ;
- *a = s6lock_zero ;
-}
diff --git a/src/libs6/s6lock_release.c b/src/libs6/s6lock_release.c
deleted file mode 100644
index 2c045a6..0000000
--- a/src/libs6/s6lock_release.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* ISC license. */
-
-#include <errno.h>
-#include <skalibs/error.h>
-#include <skalibs/uint16.h>
-#include <skalibs/gensetdyn.h>
-#include <skalibs/textclient.h>
-#include <s6/lock.h>
-
-int s6lock_release (s6lock_t *a, uint16_t i, tain const *deadline, tain *stamp)
-{
- unsigned char *p = GENSETDYN_P(unsigned char, &a->data, i) ;
- char pack[3] = "-->" ;
- if ((*p != EBUSY) && !error_isagain(*p))
- {
- s6lock_check(a, i) ;
- return 1 ;
- }
- uint16_pack_big(pack, i) ;
- if (!textclient_command(&a->connection, pack, 3, deadline, stamp)) return 0 ;
- *p = EINVAL ;
- return gensetdyn_delete(&a->data, i) ;
-}
diff --git a/src/libs6/s6lock_start.c b/src/libs6/s6lock_start.c
deleted file mode 100644
index ca8fcc8..0000000
--- a/src/libs6/s6lock_start.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* ISC license. */
-
-#include <skalibs/textclient.h>
-#include <s6/lock.h>
-
-int s6lock_start (s6lock_t *a, char const *path, tain const *deadline, tain *stamp)
-{
- return textclient_start(&a->connection, path, 0, S6LOCK_BANNER1, S6LOCK_BANNER1_LEN, S6LOCK_BANNER2, S6LOCK_BANNER2_LEN, deadline, stamp) ;
-}
diff --git a/src/libs6/s6lock_startf.c b/src/libs6/s6lock_startf.c
deleted file mode 100644
index be6e0c8..0000000
--- a/src/libs6/s6lock_startf.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/* ISC license. */
-
-#include <errno.h>
-#include <skalibs/posixplz.h>
-#include <skalibs/textclient.h>
-#include <s6/lock.h>
-
-int s6lock_startf (s6lock_t *a, char const *lockdir, tain const *deadline, tain *stamp)
-{
- char const *cargv[3] = { S6LOCKD_PROG, lockdir, 0 } ;
- if (!lockdir) return (errno = EINVAL, 0) ;
- return textclient_startf(&a->connection, cargv, (char const *const *)environ, TEXTCLIENT_OPTION_WAITPID, S6LOCK_BANNER1, S6LOCK_BANNER1_LEN, S6LOCK_BANNER2, S6LOCK_BANNER2_LEN, deadline, stamp) ;
-}
diff --git a/src/libs6/s6lock_update.c b/src/libs6/s6lock_update.c
deleted file mode 100644
index e345230..0000000
--- a/src/libs6/s6lock_update.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* ISC license. */
-
-#include <sys/uio.h>
-#include <stdint.h>
-#include <errno.h>
-
-#include <skalibs/error.h>
-#include <skalibs/uint16.h>
-#include <skalibs/genalloc.h>
-#include <skalibs/gensetdyn.h>
-#include <skalibs/textclient.h>
-
-#include <s6/lock.h>
-
-#include <skalibs/posixishard.h>
-
-static int msghandler (struct iovec const *v, void *context)
-{
- s6lock_t *a = (s6lock_t *)context ;
- char const *s = v->iov_base ;
- unsigned char *p ;
- uint16_t id ;
- if (v->iov_len != 3) return (errno = EPROTO, 0) ;
- uint16_unpack_big(s, &id) ;
- p = GENSETDYN_P(unsigned char, &a->data, id) ;
- if (*p == EBUSY) *p = s[2] ;
- else if (error_isagain(*p)) *p = s[2] ? s[2] : EBUSY ;
- else return (errno = EPROTO, 0) ;
- if (!genalloc_append(uint16_t, &a->list, &id)) return 0 ;
- return 1 ;
-}
-
-int s6lock_update (s6lock_t *a)
-{
- genalloc_setlen(uint16_t, &a->list, 0) ;
- return textclient_update(&a->connection, &msghandler, a) ;
-}
diff --git a/src/libs6/s6lock_wait_and.c b/src/libs6/s6lock_wait_and.c
deleted file mode 100644
index eca7946..0000000
--- a/src/libs6/s6lock_wait_and.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* ISC license. */
-
-#include <errno.h>
-#include <skalibs/iopause.h>
-#include <s6/lock.h>
-
-int s6lock_wait_and (s6lock_t *a, uint16_t const *idlist, unsigned int n, tain const *deadline, tain *stamp)
-{
- iopause_fd x = { .fd = -1, .events = IOPAUSE_READ, .revents = 0 } ;
- x.fd = s6lock_fd(a) ;
- for (; n ; n--, idlist++)
- {
- for (;;)
- {
- int r = s6lock_check(a, *idlist) ;
- if (r < 0) return r ;
- else if (r) break ;
- r = iopause_stamp(&x, 1, deadline, stamp) ;
- if (r < 0) return r ;
- else if (!r) return (errno = ETIMEDOUT, -1) ;
- else if (s6lock_update(a) < 0) return -1 ;
- }
- }
- return 0 ;
-}
diff --git a/src/libs6/s6lock_wait_or.c b/src/libs6/s6lock_wait_or.c
deleted file mode 100644
index 4e2a501..0000000
--- a/src/libs6/s6lock_wait_or.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* ISC license. */
-
-#include <errno.h>
-
-#include <skalibs/iopause.h>
-
-#include <s6/lock.h>
-
-#include <skalibs/posixishard.h>
-
-int s6lock_wait_or (s6lock_t *a, uint16_t const *idlist, unsigned int n, tain const *deadline, tain *stamp)
-{
- iopause_fd x = { -1, IOPAUSE_READ | IOPAUSE_EXCEPT, 0 } ;
- x.fd = s6lock_fd(a) ;
- if (x.fd < 0) return -1 ;
- for (;;)
- {
- unsigned int i = 0 ;
- int r ;
- for (; i < n ; i++)
- {
- r = s6lock_check(a, idlist[i]) ;
- if (r < 0) return r ;
- else if (r) return i ;
- }
- r = iopause_stamp(&x, 1, deadline, stamp) ;
- if (r < 0) return 0 ;
- else if (!r) return (errno = ETIMEDOUT, -1) ;
- else if (s6lock_update(a) < 0) return -1 ;
- }
- return (errno = EPROTO, -1) ; /* can't happen */
-}
diff --git a/src/libs6/s6lock_zero.c b/src/libs6/s6lock_zero.c
deleted file mode 100644
index 3d35d40..0000000
--- a/src/libs6/s6lock_zero.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* ISC license. */
-
-#include <s6/lock.h>
-
-s6lock_t const s6lock_zero = S6LOCK_ZERO ;
diff --git a/src/libs6/s6lockd-helper.c b/src/libs6/s6lockd-helper.c
deleted file mode 100644
index 7bfcf38..0000000
--- a/src/libs6/s6lockd-helper.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* ISC license. */
-
-#include <skalibs/allreadwrite.h>
-#include <skalibs/strerr.h>
-
-#include "s6lockd.h"
-
-#define USAGE "s6lockd-helper r|w lockfile"
-#define dieusage() strerr_dieusage(100, USAGE)
-
-int main (int argc, char const *const *argv)
-{
- char c ;
- PROG = "s6lockd-helper" ;
- if (argc < 3) dieusage() ;
- s6lockd_openandlock(argv[2], argv[1][0] == 'w', 0) ;
- if (fd_write(1, "!", 1) <= 0)
- strerr_diefu1sys(111, "write to stdout") ;
- if (fd_read(0, &c, 1) < 0)
- strerr_diefu1sys(111, "read from stdin") ;
- return 0 ;
-}
diff --git a/src/libs6/s6lockd.c b/src/libs6/s6lockd.c
deleted file mode 100644
index 8cc767a..0000000
--- a/src/libs6/s6lockd.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* ISC license. */
-
-#include <sys/uio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-
-#include <skalibs/posixishard.h>
-#include <skalibs/types.h>
-#include <skalibs/allreadwrite.h>
-#include <skalibs/error.h>
-#include <skalibs/strerr.h>
-#include <skalibs/genalloc.h>
-#include <skalibs/sig.h>
-#include <skalibs/selfpipe.h>
-#include <skalibs/tai.h>
-#include <skalibs/cspawn.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/iopause.h>
-#include <skalibs/textmessage.h>
-#include <skalibs/textclient.h>
-
-#include <s6/lock.h>
-
-#define USAGE "s6lockd lockdir"
-#define X() strerr_dief1x(101, "internal inconsistency, please submit a bug-report.")
-
-typedef struct s6lockio_s s6lockio_t, *s6lockio_t_ref ;
-struct s6lockio_s
-{
- unsigned int xindex ;
- unsigned int pid ;
- tain limit ;
- int p[2] ;
- uint16_t id ; /* given by client */
-} ;
-#define S6LOCKIO_ZERO { 0, 0, TAIN_ZERO, { -1, -1 }, 0 }
-static s6lockio_t const szero = S6LOCKIO_ZERO ;
-
-static genalloc a = GENALLOC_ZERO ; /* array of s6lockio_t */
-
-static void s6lockio_free (s6lockio_t *p)
-{
- int e = errno ;
- fd_close(p->p[1]) ;
- fd_close(p->p[0]) ;
- kill(p->pid, SIGTERM) ;
- *p = szero ;
- errno = e ;
-}
-
-static void cleanup (void)
-{
- size_t i = genalloc_len(s6lockio_t, &a) ;
- for (; i ; i--) s6lockio_free(genalloc_s(s6lockio_t, &a) + i - 1) ;
- genalloc_setlen(s6lockio_t, &a, 0) ;
-}
-
-static void trig (uint16_t id, unsigned char e)
-{
- char pack[3] ;
- uint16_pack_big(pack, id) ;
- pack[2] = e ;
- if (!textmessage_put(textmessage_sender_x, pack, 3))
- {
- cleanup() ;
- strerr_diefu1sys(111, "build answer") ;
- }
-}
-
-static void answer (unsigned char c)
-{
- if (!textmessage_put(textmessage_sender_1, (char *)&c, 1))
- {
- cleanup() ;
- strerr_diefu1sys(111, "textmessage_put") ;
- }
-}
-
-static void remove (unsigned int i)
-{
- size_t n = genalloc_len(s6lockio_t, &a) - 1 ;
- s6lockio_free(genalloc_s(s6lockio_t, &a) + i) ;
- genalloc_s(s6lockio_t, &a)[i] = genalloc_s(s6lockio_t, &a)[n] ;
- genalloc_setlen(s6lockio_t, &a, n) ;
-}
-
-static void handle_signals (void)
-{
- for (;;)
- {
- switch (selfpipe_read())
- {
- case -1 : cleanup() ; strerr_diefu1sys(111, "selfpipe_read") ;
- case 0 : return ;
- case SIGTERM :
- case SIGQUIT :
- case SIGHUP :
- case SIGABRT :
- case SIGINT : cleanup() ; _exit(0) ;
- case SIGCHLD : wait_reap() ; break ;
- default : cleanup() ; X() ;
- }
- }
-}
-
-static int parse_protocol (struct iovec const *v, void *context)
-{
- char *s = v->iov_base ;
- uint16_t id ;
- if (v->iov_len < 3)
- {
- cleanup() ;
- strerr_dief1x(100, "invalid client request") ;
- }
- uint16_unpack_big(s, &id) ;
- switch (s[2])
- {
- case '>' : /* release */
- {
- size_t i = genalloc_len(s6lockio_t, &a) ;
- for (; i ; i--) if (genalloc_s(s6lockio_t, &a)[i-1].id == id) break ;
- if (i)
- {
- remove(i-1) ;
- answer(0) ;
- }
- else answer(ENOENT) ;
- break ;
- }
- case '<' : /* lock path */
- {
- s6lockio_t f = S6LOCKIO_ZERO ;
- char const *cargv[4] = { S6LOCKD_HELPER_PROG, "r", 0, 0 } ;
- char const *nullenv = 0 ;
- uint32_t options, pathlen ;
- if (v->iov_len < 23)
- {
- answer(EPROTO) ;
- break ;
- }
- uint32_unpack_big(s + 3, &options) ;
- tain_unpack(s + 7, &f.limit) ;
- uint32_unpack_big(s + 19, &pathlen) ;
- if (pathlen + 23 != v->iov_len || s[v->iov_len - 1])
- {
- answer(EPROTO) ;
- break ;
- }
- f.id = id ;
- s[21] = '.' ;
- s[22] = '/' ;
- if (options & S6LOCK_OPTIONS_EX) cargv[1] = "w" ;
- cargv[2] = (char const *)s + 21 ;
- f.pid = child_spawn2(cargv[0], cargv, &nullenv, f.p) ;
- if (!f.pid)
- {
- answer(errno) ;
- break ;
- }
- if (!genalloc_append(s6lockio_t, &a, &f))
- {
- s6lockio_free(&f) ;
- answer(errno) ;
- break ;
- }
- answer(0) ;
- break ;
- }
- default :
- {
- cleanup() ;
- strerr_dief1x(100, "invalid client request") ;
- }
- }
- (void)context ;
- return 1 ;
-}
-
-int main (int argc, char const *const *argv)
-{
- tain deadline ;
- PROG = "s6lockd" ;
-
- if (argc < 2) strerr_dieusage(100, USAGE) ;
- if (chdir(argv[1]) < 0) strerr_diefu2sys(111, "chdir to ", argv[1]) ;
- if (ndelay_on(0) < 0) strerr_diefu2sys(111, "ndelay_on ", "0") ;
- if (ndelay_on(1) < 0) strerr_diefu2sys(111, "ndelay_on ", "1") ;
- if (!sig_altignore(SIGPIPE)) strerr_diefu1sys(111, "ignore SIGPIPE") ;
-
- if (selfpipe_init() == -1) strerr_diefu1sys(111, "selfpipe_init") ;
- {
- sigset_t set ;
- sigemptyset(&set) ;
- sigaddset(&set, SIGCHLD) ;
- sigaddset(&set, SIGTERM) ;
- sigaddset(&set, SIGQUIT) ;
- sigaddset(&set, SIGHUP) ;
- sigaddset(&set, SIGABRT) ;
- sigaddset(&set, SIGINT) ;
- if (!selfpipe_trapset(&set))
- strerr_diefu1sys(111, "trap signals") ;
- }
-
- tain_now_set_stopwatch_g() ;
- tain_addsec_g(&deadline, 2) ;
-
- if (!textclient_server_01x_init_g(S6LOCK_BANNER1, S6LOCK_BANNER1_LEN, S6LOCK_BANNER2, S6LOCK_BANNER2_LEN, &deadline))
- strerr_diefu1sys(111, "sync with client") ;
-
- for (;;)
- {
- size_t n = genalloc_len(s6lockio_t, &a) ;
- iopause_fd x[4 + n] ;
- unsigned int i = 0 ;
- int r ;
-
- tain_add_g(&deadline, &tain_infinite_relative) ;
- x[0].fd = 0 ; x[0].events = IOPAUSE_EXCEPT | IOPAUSE_READ ;
- x[1].fd = 1 ; x[1].events = IOPAUSE_EXCEPT | (textmessage_sender_isempty(textmessage_sender_1) ? 0 : IOPAUSE_WRITE ) ;
- x[2].fd = textmessage_sender_fd(textmessage_sender_x) ;
- x[2].events = IOPAUSE_EXCEPT | (textmessage_sender_isempty(textmessage_sender_x) ? 0 : IOPAUSE_WRITE) ;
- x[3].fd = selfpipe_fd() ; x[3].events = IOPAUSE_READ ;
- for (; i < n ; i++)
- {
- s6lockio_t *p = genalloc_s(s6lockio_t, &a) + i ;
- x[4+i].fd = p->p[0] ;
- x[4+i].events = IOPAUSE_READ ;
- if (p->limit.sec.x && tain_less(&p->limit, &deadline)) deadline = p->limit ;
- p->xindex = 4+i ;
- }
-
- r = iopause_g(x, 4 + n, &deadline) ;
- if (r < 0)
- {
- cleanup() ;
- strerr_diefu1sys(111, "iopause") ;
- }
-
- /* timeout => seek and destroy */
- if (!r)
- {
- for (i = 0 ; i < n ; i++)
- {
- s6lockio_t *p = genalloc_s(s6lockio_t, &a) + i ;
- if (p->limit.sec.x && !tain_future(&p->limit)) break ;
- }
- if (i < n)
- {
- trig(genalloc_s(s6lockio_t, &a)[i].id, ETIMEDOUT) ;
- remove(i) ;
- }
- continue ;
- }
-
- /* client closed */
- if ((x[0].revents | x[1].revents) & IOPAUSE_EXCEPT) break ;
-
- /* client is reading */
- if (x[1].revents & IOPAUSE_WRITE)
- if (!textmessage_sender_flush(textmessage_sender_1) && !error_isagain(errno))
- {
- cleanup() ;
- strerr_diefu1sys(111, "flush stdout") ;
- }
- if (x[2].revents & IOPAUSE_WRITE)
- if (!textmessage_sender_flush(textmessage_sender_x) && !error_isagain(errno))
- {
- cleanup() ;
- strerr_diefu1sys(111, "flush asyncout") ;
- }
-
- /* scan children for successes */
- for (i = 0 ; i < genalloc_len(s6lockio_t, &a) ; i++)
- {
- s6lockio_t *p = genalloc_s(s6lockio_t, &a) + i ;
- if (p->p[0] < 0) continue ;
- if (x[p->xindex].revents & IOPAUSE_READ)
- {
- char c ;
- ssize_t r = sanitize_read(fd_read(p->p[0], &c, 1)) ;
- if (!r) continue ;
- if (r < 0)
- {
- trig(p->id, errno) ;
- remove(i--) ;
- }
- else if (c != '!')
- {
- trig(p->id, EPROTO) ;
- remove(i--) ;
- }
- else
- {
- trig(p->id, 0) ;
- p->limit = tain_zero ;
- }
- }
- }
-
- /* signals arrived */
- if (x[3].revents & (IOPAUSE_READ | IOPAUSE_EXCEPT)) handle_signals() ;
-
- /* client is writing */
- if (!textmessage_receiver_isempty(textmessage_receiver_0) || x[0].revents & IOPAUSE_READ)
- {
- if (textmessage_handle(textmessage_receiver_0, &parse_protocol, 0) < 0)
- {
- if (errno == EPIPE) break ; /* normal exit */
- cleanup() ;
- strerr_diefu1sys(111, "handle messages from client") ;
- }
- }
- }
- cleanup() ;
- return 0 ;
-}
diff --git a/src/libs6/s6lockd_openandlock.c b/src/libs6/s6lockd_openandlock.c
deleted file mode 100644
index ca51934..0000000
--- a/src/libs6/s6lockd_openandlock.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* ISC license. */
-
-#include <errno.h>
-
-#include <skalibs/strerr.h>
-#include <skalibs/djbunix.h>
-
-#include "s6lockd.h"
-
-int s6lockd_openandlock (char const *file, int ex, int nb)
-{
- int fd, r ;
- if (ex)
- {
- fd = open_create(file) ;
- if (fd < 0) strerr_diefu3sys(111, "open ", file, " for writing") ;
- }
- else
- {
- fd = open_read(file) ;
- if (fd < 0)
- {
- if (errno != ENOENT) strerr_diefu3sys(111, "open ", file, " for reading") ;
- fd = open_create(file) ;
- if (fd < 0) strerr_diefu2sys(111, "create ", file) ;
- fd_close(fd) ;
- fd = open_read(file) ;
- if (fd < 0) strerr_diefu3sys(111, "open ", file, " for reading") ;
- }
- }
- r = fd_lock(fd, ex, nb) ;
- if (!r) errno = EBUSY ;
- if (r < 1) strerr_diefu2sys(1, "lock ", file) ;
- return fd ;
-}