summaryrefslogtreecommitdiff
path: root/src/libstddjb
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2020-11-29 21:02:32 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2020-11-29 21:02:32 +0000
commit90b819c6d832046840018ff08b9bc5d0e3b69c37 (patch)
treeefea05788cc982395ee114474d84096e7fc70862 /src/libstddjb
parente6c5c984461dc4cec0ef2d68524d6bd457e23853 (diff)
downloadskalibs-90b819c6d832046840018ff08b9bc5d0e3b69c37.tar.xz
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.
Diffstat (limited to 'src/libstddjb')
-rw-r--r--src/libstddjb/fd_islocked.c17
-rw-r--r--src/libstddjb/fd_lock.c25
-rw-r--r--src/libstddjb/fd_unlock.c20
-rw-r--r--src/libstddjb/ipc_bind_reuse_lock.c6
-rw-r--r--src/libstddjb/lock_ex.c34
-rw-r--r--src/libstddjb/lock_exnb.c35
-rw-r--r--src/libstddjb/lock_sh.c34
-rw-r--r--src/libstddjb/lock_shnb.c35
-rw-r--r--src/libstddjb/lock_un.c34
-rw-r--r--src/libstddjb/lock_unx.c11
10 files changed, 67 insertions, 184 deletions
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 <fcntl.h>
+
+#include <skalibs/djbunix.h>
+
+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 <fcntl.h>
+#include <errno.h>
+
+#include <skalibs/error.h>
+#include <skalibs/djbunix.h>
+
+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 <fcntl.h>
+#include <errno.h>
+
+#include <skalibs/djbunix.h>
+
+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 <string.h>
#include <unistd.h>
+#include <errno.h>
#include <sys/socket.h>
#include <skalibs/djbunix.h>
@@ -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 <skalibs/sysdeps.h>
-
-#ifdef SKALIBS_HASFLOCK
-
-#include <skalibs/nonposix.h>
-#include <errno.h>
-#include <sys/file.h>
-#include <skalibs/djbunix.h>
-
-int lock_ex (int fd)
-{
- int r ;
- do r = flock(fd, LOCK_EX) ;
- while ((r == -1) && (errno == EINTR)) ;
- return r ;
-}
-
-#else
-
-#include <unistd.h>
-#include <errno.h>
-#include <skalibs/djbunix.h>
-
-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 <skalibs/sysdeps.h>
-
-#ifdef SKALIBS_HASFLOCK
-
-#include <skalibs/nonposix.h>
-#include <errno.h>
-#include <sys/file.h>
-#include <skalibs/djbunix.h>
-
-int lock_exnb (int fd)
-{
- int r ;
- do r = flock(fd, LOCK_EX | LOCK_NB) ;
- while ((r == -1) && (errno == EINTR)) ;
- return r ;
-}
-
-#else
-
-#include <unistd.h>
-#include <errno.h>
-#include <skalibs/djbunix.h>
-
-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 <skalibs/sysdeps.h>
-
-#ifdef SKALIBS_HASFLOCK
-
-#include <skalibs/nonposix.h>
-#include <errno.h>
-#include <sys/file.h>
-#include <skalibs/djbunix.h>
-
-int lock_sh (int fd)
-{
- int r ;
- do r = flock(fd, LOCK_SH) ;
- while ((r == -1) && (errno == EINTR)) ;
- return r ;
-}
-
-#else
-
-#include <unistd.h>
-#include <errno.h>
-#include <skalibs/djbunix.h>
-
-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 <skalibs/sysdeps.h>
-
-#ifdef SKALIBS_HASFLOCK
-
-#include <skalibs/nonposix.h>
-#include <errno.h>
-#include <sys/file.h>
-#include <skalibs/djbunix.h>
-
-int lock_shnb (int fd)
-{
- int r ;
- do r = flock(fd, LOCK_SH | LOCK_NB) ;
- while ((r == -1) && (errno == EINTR)) ;
- return r ;
-}
-
-#else
-
-#include <unistd.h>
-#include <errno.h>
-#include <skalibs/djbunix.h>
-
-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 <skalibs/sysdeps.h>
-
-#ifdef SKALIBS_HASFLOCK
-
-#include <skalibs/nonposix.h>
-#include <errno.h>
-#include <sys/file.h>
-#include <skalibs/djbunix.h>
-
-int lock_un (int fd)
-{
- int r ;
- do r = flock(fd, LOCK_UN) ;
- while ((r == -1) && (errno == EINTR)) ;
- return r ;
-}
-
-#else
-
-#include <unistd.h>
-#include <errno.h>
-#include <skalibs/djbunix.h>
-
-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 <errno.h>
-#include <skalibs/djbunix.h>
-
-void lock_unx (int fd)
-{
- int e = errno ;
- lock_un(fd) ;
- errno = e ;
-}