From 90b819c6d832046840018ff08b9bc5d0e3b69c37 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Sun, 29 Nov 2020 21:02:32 +0000 Subject: Revamp lock primitives; prepare for 2.10.0.0 instead of 2.9.4.0 flock() doesn't have a way to test for a lock without taking it. lockf() doesn't have shared locks. The only way to have both is fcntl(). So I rewrote all the locking stuff around fcntl(), and used the opportunity to change the interface. The point of changing the interface is to stop having to bother with the old one, so to hell with compatibility, let's just do a major bump. --- src/include/skalibs/djbunix.h | 12 +++++------- src/include/skalibs/exec.h | 2 ++ src/libstddjb/fd_islocked.c | 17 +++++++++++++++++ src/libstddjb/fd_lock.c | 25 +++++++++++++++++++++++++ src/libstddjb/fd_unlock.c | 20 ++++++++++++++++++++ src/libstddjb/ipc_bind_reuse_lock.c | 6 +++++- src/libstddjb/lock_ex.c | 34 ---------------------------------- src/libstddjb/lock_exnb.c | 35 ----------------------------------- src/libstddjb/lock_sh.c | 34 ---------------------------------- src/libstddjb/lock_shnb.c | 35 ----------------------------------- src/libstddjb/lock_un.c | 34 ---------------------------------- src/libstddjb/lock_unx.c | 11 ----------- 12 files changed, 74 insertions(+), 191 deletions(-) create mode 100644 src/libstddjb/fd_islocked.c create mode 100644 src/libstddjb/fd_lock.c create mode 100644 src/libstddjb/fd_unlock.c delete mode 100644 src/libstddjb/lock_ex.c delete mode 100644 src/libstddjb/lock_exnb.c delete mode 100644 src/libstddjb/lock_sh.c delete mode 100644 src/libstddjb/lock_shnb.c delete mode 100644 src/libstddjb/lock_un.c delete mode 100644 src/libstddjb/lock_unx.c (limited to 'src') diff --git a/src/include/skalibs/djbunix.h b/src/include/skalibs/djbunix.h index 885a623..1f356e1 100644 --- a/src/include/skalibs/djbunix.h +++ b/src/include/skalibs/djbunix.h @@ -9,7 +9,6 @@ #include #include -#include /* compat */ #define DJBUNIX_FLAG_NB 0x01U #define DJBUNIX_FLAG_COE 0x02U @@ -35,12 +34,11 @@ extern size_t fd_catn (int, int, size_t) ; extern int fd_ensure_open (int, int) ; #define fd_sanitize() (fd_ensure_open(0, 0) && fd_ensure_open(1, 1) && fd_ensure_open(2, 1)) extern void fd_shutdown (int, int) ; -extern int lock_ex (int) ; -extern int lock_exnb (int) ; -extern int lock_sh (int) ; -extern int lock_shnb (int) ; -extern int lock_un (int) ; -extern void lock_unx (int) ; + +extern int fd_lock (int, int, int) ; +extern void fd_unlock (int) ; +extern int fd_islocked (int) ; + extern int open2 (char const *, unsigned int) ; extern int open3 (char const *, unsigned int, unsigned int) ; extern int open_read (char const *) ; diff --git a/src/include/skalibs/exec.h b/src/include/skalibs/exec.h index d32d3dc..67fed27 100644 --- a/src/include/skalibs/exec.h +++ b/src/include/skalibs/exec.h @@ -139,6 +139,7 @@ extern void xmexec0_af (char const *, char const *const *, char const *const *, /* Compatibility */ +#if 0 #define pathexec_run(file, argv, envp) exec_ae(file, argv, envp) #define pathexec0_run(argv, envp) exec0_e(argv, envp) #define xpathexec_run(file, argv, envp) xexec_ae(file, argv, envp) @@ -156,5 +157,6 @@ extern void xmexec0_af (char const *, char const *const *, char const *const *, #define pathexec_r(argv, envp, envlen, modif, modiflen) mexec_fm(argv, envp, envlen, modif, modiflen) #define xpathexec_r_name(file, argv, envp, envlen, modif, modiflen) xmexec_afm(file, argv, envp, envlen, modif, modiflen) #define xpathexec_r(argv, envp, envlen, modif, modiflen) xmexec_fm(argv, envp, envlen, modif, modiflen) +#endif #endif diff --git a/src/libstddjb/fd_islocked.c b/src/libstddjb/fd_islocked.c new file mode 100644 index 0000000..bf9f9e8 --- /dev/null +++ b/src/libstddjb/fd_islocked.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include + +#include + +int fd_islocked (int fd) +{ + struct flock fl = + { + .l_type = F_RDLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 0 + } ; + return fcntl(fd, F_GETLK, &fl) < 0 ? -1 : fl.l_type != F_UNLCK ; +} diff --git a/src/libstddjb/fd_lock.c b/src/libstddjb/fd_lock.c new file mode 100644 index 0000000..422e667 --- /dev/null +++ b/src/libstddjb/fd_lock.c @@ -0,0 +1,25 @@ +/* ISC license. */ + +#include +#include + +#include +#include + +int fd_lock (int fd, int w, int nb) +{ + struct flock fl = + { + .l_type = w ? F_WRLCK : F_RDLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 0 + } ; + int e = errno ; + int r ; + do r = fcntl(fd, nb ? F_SETLK : F_SETLKW, &fl) ; + while (r < 0 && errno == EINTR) ; + return r >= 0 ? 1 : + errno == EACCES || error_isagain(errno) ? (errno = e, 0) : + -1 ; +} diff --git a/src/libstddjb/fd_unlock.c b/src/libstddjb/fd_unlock.c new file mode 100644 index 0000000..4c63fd9 --- /dev/null +++ b/src/libstddjb/fd_unlock.c @@ -0,0 +1,20 @@ +/* ISC license. */ + +#include +#include + +#include + +void fd_unlock (int fd) +{ + struct flock fl = + { + .l_type = F_UNLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 0 + } ; + int e = errno ; + fcntl(fd, F_SETLK, &fl) ; + errno = e ; +} diff --git a/src/libstddjb/ipc_bind_reuse_lock.c b/src/libstddjb/ipc_bind_reuse_lock.c index aede744..b1bccfd 100644 --- a/src/libstddjb/ipc_bind_reuse_lock.c +++ b/src/libstddjb/ipc_bind_reuse_lock.c @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -14,12 +15,15 @@ int ipc_bind_reuse_lock (int s, char const *p, int *fdlock) unsigned int opt = 1 ; size_t len = strlen(p) ; int fd ; + int r ; char lockname[len + 6] ; memcpy(lockname, p, len) ; memcpy(lockname + len, ".lock", 6) ; fd = openc_create(lockname) ; if (fd < 0) return -1 ; - if (lock_exnb(fd) < 0) return -1 ; + r = fd_lock(fd, 1, 1) ; + if (r < 0) return -1 ; + if (!r) return (errno = EBUSY, -1) ; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt) ; unlink(p) ; if (ipc_bind(s, p) < 0) return -1 ; diff --git a/src/libstddjb/lock_ex.c b/src/libstddjb/lock_ex.c deleted file mode 100644 index 2645fab..0000000 --- a/src/libstddjb/lock_ex.c +++ /dev/null @@ -1,34 +0,0 @@ -/* ISC license. */ - -#include - -#ifdef SKALIBS_HASFLOCK - -#include -#include -#include -#include - -int lock_ex (int fd) -{ - int r ; - do r = flock(fd, LOCK_EX) ; - while ((r == -1) && (errno == EINTR)) ; - return r ; -} - -#else - -#include -#include -#include - -int lock_ex (int fd) -{ - int r ; - do r = lockf(fd, F_LOCK, 0) ; - while ((r == -1) && (errno == EINTR)) ; - return r ; -} - -#endif diff --git a/src/libstddjb/lock_exnb.c b/src/libstddjb/lock_exnb.c deleted file mode 100644 index 7d5302f..0000000 --- a/src/libstddjb/lock_exnb.c +++ /dev/null @@ -1,35 +0,0 @@ -/* ISC license. */ - -#include - -#ifdef SKALIBS_HASFLOCK - -#include -#include -#include -#include - -int lock_exnb (int fd) -{ - int r ; - do r = flock(fd, LOCK_EX | LOCK_NB) ; - while ((r == -1) && (errno == EINTR)) ; - return r ; -} - -#else - -#include -#include -#include - -int lock_exnb (int fd) -{ - int r ; - do r = lockf(fd, F_TLOCK, 0) ; - while ((r == -1) && (errno == EINTR)) ; - if ((r == -1) && (errno == EACCES)) errno = EAGAIN ; - return r ; -} - -#endif diff --git a/src/libstddjb/lock_sh.c b/src/libstddjb/lock_sh.c deleted file mode 100644 index c942d0d..0000000 --- a/src/libstddjb/lock_sh.c +++ /dev/null @@ -1,34 +0,0 @@ -/* ISC license. */ - -#include - -#ifdef SKALIBS_HASFLOCK - -#include -#include -#include -#include - -int lock_sh (int fd) -{ - int r ; - do r = flock(fd, LOCK_SH) ; - while ((r == -1) && (errno == EINTR)) ; - return r ; -} - -#else - -#include -#include -#include - -int lock_sh (int fd) -{ - int r ; - do r = lockf(fd, F_LOCK, 0) ; - while ((r == -1) && (errno == EINTR)) ; - return r ; -} - -#endif diff --git a/src/libstddjb/lock_shnb.c b/src/libstddjb/lock_shnb.c deleted file mode 100644 index 40c988d..0000000 --- a/src/libstddjb/lock_shnb.c +++ /dev/null @@ -1,35 +0,0 @@ -/* ISC license. */ - -#include - -#ifdef SKALIBS_HASFLOCK - -#include -#include -#include -#include - -int lock_shnb (int fd) -{ - int r ; - do r = flock(fd, LOCK_SH | LOCK_NB) ; - while ((r == -1) && (errno == EINTR)) ; - return r ; -} - -#else - -#include -#include -#include - -int lock_shnb (int fd) -{ - int r ; - do r = lockf(fd, F_TLOCK, 0) ; - while ((r == -1) && (errno == EINTR)) ; - if ((r == -1) && (errno == EACCES)) errno = EAGAIN ; - return r ; -} - -#endif diff --git a/src/libstddjb/lock_un.c b/src/libstddjb/lock_un.c deleted file mode 100644 index a029a7c..0000000 --- a/src/libstddjb/lock_un.c +++ /dev/null @@ -1,34 +0,0 @@ -/* ISC license. */ - -#include - -#ifdef SKALIBS_HASFLOCK - -#include -#include -#include -#include - -int lock_un (int fd) -{ - int r ; - do r = flock(fd, LOCK_UN) ; - while ((r == -1) && (errno == EINTR)) ; - return r ; -} - -#else - -#include -#include -#include - -int lock_un (int fd) -{ - int r ; - do r = lockf(fd, F_ULOCK, 0) ; - while ((r == -1) && (errno == EINTR)) ; - return r ; -} - -#endif diff --git a/src/libstddjb/lock_unx.c b/src/libstddjb/lock_unx.c deleted file mode 100644 index d2f8483..0000000 --- a/src/libstddjb/lock_unx.c +++ /dev/null @@ -1,11 +0,0 @@ -/* ISC license. */ - -#include -#include - -void lock_unx (int fd) -{ - int e = errno ; - lock_un(fd) ; - errno = e ; -} -- cgit v1.2.3