From 65e6a29abd7413e21cc45470561e0eee2b24549e Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Mon, 26 Oct 2020 09:33:06 +0000 Subject: Prepare for 2.9.2.1; add dangling symlink support --- src/libs6/s6_supervise_lock_mode.c | 44 +++++++++++++++++++++++++++++++------- src/libs6/s6_svc_lock_take.c | 6 ++++-- 2 files changed, 40 insertions(+), 10 deletions(-) (limited to 'src/libs6') diff --git a/src/libs6/s6_supervise_lock_mode.c b/src/libs6/s6_supervise_lock_mode.c index 039760c..710e3ba 100644 --- a/src/libs6/s6_supervise_lock_mode.c +++ b/src/libs6/s6_supervise_lock_mode.c @@ -1,12 +1,22 @@ /* ISC license. */ +#include +#include #include #include #include + #include #include + #include +#ifdef PATH_MAX +# define S6_PATH_MAX PATH_MAX +#else +# define S6_PATH_MAX 4096 +#endif + int s6_supervise_lock_mode (char const *subdir, unsigned int subdirmode, unsigned int controlmode) { size_t subdirlen = strlen(subdir) ; @@ -17,8 +27,28 @@ int s6_supervise_lock_mode (char const *subdir, unsigned int subdirmode, unsigne memcpy(control + subdirlen, "/control", 9) ; memcpy(lock, subdir, subdirlen) ; memcpy(lock + subdirlen, "/lock", 6) ; - if ((mkdir(subdir, (mode_t)subdirmode) == -1) && (errno != EEXIST)) - strerr_diefu2sys(111, "mkdir ", subdir) ; + if (mkdir(subdir, (mode_t)subdirmode) == -1) + { + if (errno != EEXIST) strerr_diefu2sys(111, "mkdir ", subdir) ; + else + { + char buf[S6_PATH_MAX] ; + ssize_t r = readlink(subdir, buf, S6_PATH_MAX) ; + if (r < 0) + { + errno = EEXIST ; + strerr_diefu2sys(111, "mkdir ", subdir) ; + } + if (r == S6_PATH_MAX) + { + errno = ENAMETOOLONG ; + strerr_diefu2sys(111, "readlink ", subdir) ; + } + buf[r] = 0 ; + if (mkdir(buf, (mode_t)subdirmode) == -1) + strerr_diefu2sys(111, "mkdir ", buf) ; + } + } if (mkfifo(control, controlmode) < 0) { struct stat st ; @@ -29,24 +59,22 @@ int s6_supervise_lock_mode (char const *subdir, unsigned int subdirmode, unsigne if (!S_ISFIFO(st.st_mode)) strerr_diefu2x(100, control, " is not a FIFO") ; } - fdlock = open_create(lock) ; + fdlock = open_createcoe(lock) ; if (fdlock < 0) strerr_diefu2sys(111, "open_create ", lock) ; if (lock_ex(fdlock) < 0) strerr_diefu2sys(111, "lock ", lock) ; - fdctlw = open_write(control) ; + fdctlw = open_writecoe(control) ; if (fdctlw >= 0) strerr_dief1x(100, "directory already locked") ; if (errno != ENXIO) strerr_diefu2sys(111, "open_write ", control) ; - fdctl = open_read(control) ; + fdctl = open_readcoe(control) ; if (fdctl < 0) strerr_diefu2sys(111, "open_read ", control) ; - fdctlw = open_write(control) ; + fdctlw = open_writecoe(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. */ diff --git a/src/libs6/s6_svc_lock_take.c b/src/libs6/s6_svc_lock_take.c index 3dec282..a98aeab 100644 --- a/src/libs6/s6_svc_lock_take.c +++ b/src/libs6/s6_svc_lock_take.c @@ -6,6 +6,8 @@ #include #include + /* XXX: does not work with dangling S6_SUPERVISE_CTLDIR symlinks */ + int s6_svc_lock_take (char const *dir) { size_t dirlen = strlen(dir) ; @@ -15,9 +17,9 @@ int s6_svc_lock_take (char const *dir) memcpy(lock + dirlen, "/" S6_SUPERVISE_CTLDIR, sizeof(S6_SUPERVISE_CTLDIR) + 1) ; if ((mkdir(lock, S_IRWXU) < 0) && (errno != EEXIST)) return -1 ; memcpy(lock + dirlen + sizeof(S6_SUPERVISE_CTLDIR), "/lock", 6) ; - fdlock = open_create(lock) ; + fdlock = open_createcoe(lock) ; if (fdlock < 0) return -1 ; - if (coe(fdlock) < 0 || lock_ex(fdlock) < 0) + if (lock_ex(fdlock) < 0) { fd_close(fdlock) ; return -1 ; -- cgit v1.2.3