summaryrefslogtreecommitdiff
path: root/src/supervision/s6-supervise.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2020-12-02 05:24:24 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2020-12-02 05:24:24 +0000
commit8873c303fefaed17f6777989f929612a99675a00 (patch)
tree26efa9863177ec574d4351e8db84a47566a2af98 /src/supervision/s6-supervise.c
parent2a73901e12a1f3b498e6901ef607b55f9f193097 (diff)
downloads6-8873c303fefaed17f6777989f929612a99675a00.tar.xz
Fix build against skalibs-2.10.0.0
Diffstat (limited to 'src/supervision/s6-supervise.c')
-rw-r--r--src/supervision/s6-supervise.c95
1 files changed, 91 insertions, 4 deletions
diff --git a/src/supervision/s6-supervise.c b/src/supervision/s6-supervise.c
index da6a187..112ccea 100644
--- a/src/supervision/s6-supervise.c
+++ b/src/supervision/s6-supervise.c
@@ -3,13 +3,16 @@
/* For SIGWINCH */
#include <skalibs/nonposix.h>
-#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <signal.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
#include <skalibs/allreadwrite.h>
#include <skalibs/bytestr.h>
#include <skalibs/types.h>
@@ -20,10 +23,19 @@
#include <skalibs/sig.h>
#include <skalibs/selfpipe.h>
#include <skalibs/skamisc.h>
+
#include <s6/ftrigw.h>
#include <s6/s6-supervise.h>
#define USAGE "s6-supervise dir"
+#define CTL S6_SUPERVISE_CTLDIR "/control"
+#define LCK S6_SUPERVISE_CTLDIR "/lock"
+
+#ifdef PATH_MAX
+# define S6_PATH_MAX PATH_MAX
+#else
+# define S6_PATH_MAX 4096
+#endif
typedef enum trans_e trans_t, *trans_t_ref ;
enum trans_e
@@ -625,6 +637,83 @@ static inline void handle_control (int fd)
}
}
+static int trymkdir (char const *s)
+{
+ char buf[S6_PATH_MAX] ;
+ ssize_t r ;
+ if (mkdir(s, 0700) >= 0) return 1 ;
+ if (errno != EEXIST) strerr_diefu2sys(111, "mkdir ", s) ;
+ r = readlink(s, buf, S6_PATH_MAX) ;
+ if (r < 0)
+ {
+ struct stat st ;
+ if (errno != EINVAL)
+ {
+ errno = EEXIST ;
+ strerr_diefu2sys(111, "mkdir ", s) ;
+ }
+ if (stat(s, &st) < 0)
+ strerr_diefu2sys(111, "stat ", s) ;
+ if (!S_ISDIR(st.st_mode))
+ strerr_dief2x(100, s, " exists and is not a directory") ;
+ return 0 ;
+ }
+ else if (r == S6_PATH_MAX)
+ {
+ errno = ENAMETOOLONG ;
+ strerr_diefu2sys(111, "readlink ", s) ;
+ }
+ else
+ {
+ buf[r] = 0 ;
+ if (mkdir(buf, 0700) < 0)
+ strerr_diefu2sys(111, "mkdir ", buf) ;
+ return 1 ;
+ }
+}
+
+static inline int control_init (void)
+{
+ mode_t m = umask(0) ;
+ int fdctl, fdlck, r ;
+ if (trymkdir(S6_SUPERVISE_EVENTDIR))
+ {
+ if (chown(S6_SUPERVISE_EVENTDIR, -1, getegid()) < 0)
+ strerr_diefu1sys(111, "chown " S6_SUPERVISE_EVENTDIR) ;
+ if (chmod(S6_SUPERVISE_EVENTDIR, 03730) < 0)
+ strerr_diefu1sys(111, "chmod " S6_SUPERVISE_EVENTDIR) ;
+ }
+
+ trymkdir(S6_SUPERVISE_CTLDIR) ;
+ fdlck = open(LCK, O_WRONLY | O_NONBLOCK | O_CREAT | O_CLOEXEC, 0600) ;
+ if (fdlck < 0) strerr_diefu1sys(111, "open " LCK) ;
+ r = fd_lock(fdlck, 1, 1) ;
+ if (r < 0) strerr_diefu1sys(111, "lock " LCK) ;
+ if (!r) strerr_dief1x(100, "another instance of s6-supervise is already running") ;
+ /* fdlck leaks but it's coe */
+
+ if (mkfifo(CTL, 0600) < 0)
+ {
+ struct stat st ;
+ if (errno != EEXIST)
+ strerr_diefu1sys(111, "mkfifo " CTL) ;
+ if (stat(CTL, &st) < 0)
+ strerr_diefu1sys(111, "stat " CTL) ;
+ if (!S_ISFIFO(st.st_mode))
+ strerr_dief1x(100, CTL " is not a FIFO") ;
+ }
+ fdctl = openc_read(CTL) ;
+ if (fdctl < 0)
+ strerr_diefu1sys(111, "open " CTL " for reading") ;
+ r = openc_write(CTL) ;
+ if (r < 0)
+ strerr_diefu1sys(111, "open " CTL " for writing") ;
+ /* r leaks but it's coe */
+
+ umask(m) ;
+ return fdctl ;
+}
+
int main (int argc, char const *const *argv)
{
iopause_fd x[3] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ;
@@ -640,9 +729,7 @@ int main (int argc, char const *const *argv)
memcpy(progname + proglen + 1, argv[1], namelen + 1) ;
PROG = progname ;
if (!fd_sanitize()) strerr_diefu1sys(111, "sanitize stdin and stdout") ;
- if (!ftrigw_fifodir_make(S6_SUPERVISE_EVENTDIR, getegid(), 0))
- strerr_diefu2sys(111, "mkfifodir ", S6_SUPERVISE_EVENTDIR) ;
- x[1].fd = s6_supervise_lock(S6_SUPERVISE_CTLDIR) ;
+ x[1].fd = control_init() ;
x[0].fd = selfpipe_init() ;
if (x[0].fd == -1) strerr_diefu1sys(111, "init selfpipe") ;
if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ;