summaryrefslogtreecommitdiff
path: root/src/libs6/s6_supervise_lock_mode.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2014-12-05 22:26:11 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2014-12-05 22:26:11 +0000
commit90b12bd71bb9fc79a4640b9112c13ef529d0196a (patch)
tree523b3f4ee2969e7a729bab2ba749c4b924ae62af /src/libs6/s6_supervise_lock_mode.c
downloads6-90b12bd71bb9fc79a4640b9112c13ef529d0196a.tar.xz
Initial commit
Diffstat (limited to 'src/libs6/s6_supervise_lock_mode.c')
-rw-r--r--src/libs6/s6_supervise_lock_mode.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/libs6/s6_supervise_lock_mode.c b/src/libs6/s6_supervise_lock_mode.c
new file mode 100644
index 0000000..ff3e11e
--- /dev/null
+++ b/src/libs6/s6_supervise_lock_mode.c
@@ -0,0 +1,54 @@
+/* ISC license. */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/strerr2.h>
+#include <skalibs/djbunix.h>
+#include <s6/s6-supervise.h>
+
+int s6_supervise_lock_mode (char const *subdir, unsigned int subdirmode, unsigned int controlmode)
+{
+ unsigned int subdirlen = str_len(subdir) ;
+ int fdctl, fdctlw, fdlock ;
+ char control[subdirlen + 9] ;
+ char lock[subdirlen + 6] ;
+ byte_copy(control, subdirlen, subdir) ;
+ byte_copy(control + subdirlen, 9, "/control") ;
+ byte_copy(lock, subdirlen, subdir) ;
+ byte_copy(lock + subdirlen, 6, "/lock") ;
+ if ((mkdir(subdir, (mode_t)subdirmode) == -1) && (errno != EEXIST))
+ strerr_diefu2sys(111, "mkdir ", subdir) ;
+ if (mkfifo(control, controlmode) < 0)
+ {
+ struct stat st ;
+ if (errno != EEXIST)
+ strerr_diefu2sys(111, "mkfifo ", control) ;
+ if (stat(control, &st) < 0)
+ strerr_diefu2sys(111, "stat ", control) ;
+ if (!S_ISFIFO(st.st_mode))
+ strerr_diefu2x(100, control, " is not a FIFO") ;
+ }
+ fdlock = open_create(lock) ;
+ if (fdlock < 0)
+ strerr_diefu2sys(111, "open_create ", lock) ;
+ if (lock_ex(fdlock) < 0)
+ strerr_diefu2sys(111, "lock ", lock) ;
+ fdctlw = open_write(control) ;
+ if (fdctlw >= 0) strerr_dief1x(100, "directory already locked") ;
+ if (errno != ENXIO)
+ strerr_diefu2sys(111, "open_write ", control) ;
+ fdctl = open_read(control) ;
+ if (fdctl < 0)
+ strerr_diefu2sys(111, "open_read ", control) ;
+ fdctlw = open_write(control) ;
+ if (fdctlw < 0)
+ strerr_diefu2sys(111, "open_write ", control) ;
+ fd_close(fdlock) ;
+ if ((coe(fdctlw) < 0) || (coe(fdctl) < 0))
+ strerr_diefu2sys(111, "coe ", control) ;
+
+ return fdctl ;
+ /* fdctlw is leaking. That's okay, it's coe. */
+}