Use lockf() when flock() is not available On Solaris flock() is not available, and we should use instead lockf() or fcntl().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
diff --git a/configure.ac b/configure.ac
index 78a4c97..17978b1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -290,6 +290,7 @@ __register_atfork(NULL, NULL, NULL, __dso_handle);
AC_CHECK_FUNCS([\
clearenv \
dirfd \
+ flock \
fopencookie \
__fpurge \
getauxval \
diff --git a/src/flopen.c b/src/flopen.c
index ff20d07..679445f 100644
--- a/src/flopen.c
+++ b/src/flopen.c
@@ -38,6 +38,27 @@
#include <libutil.h>
+static int
+lock_file(int fd, int flags)
+{
+ int operation;
+
+#if HAVE_FLOCK
+ operation = LOCK_EX;
+ if (flags & O_NONBLOCK)
+ operation |= LOCK_NB;
+
+ return flock(fd, operation);
+#else
+ if (flags & O_NONBLOCK)
+ operation = F_TLOCK;
+ else
+ operation = F_LOCK;
+
+ return lockf(fd, operation, 0);
+#endif
+}
+
/*
* Reliably open and lock a file.
*
@@ -49,7 +70,7 @@
static int
vflopenat(int dirfd, const char *path, int flags, va_list ap)
{
- int fd, operation, serrno, trunc;
+ int fd, serrno, trunc;
struct stat sb, fsb;
mode_t mode;
@@ -62,10 +83,6 @@ vflopenat(int dirfd, const char *path, int flags, va_list ap)
mode = (mode_t)va_arg(ap, int); /* mode_t promoted to int */
}
- operation = LOCK_EX;
- if (flags & O_NONBLOCK)
- operation |= LOCK_NB;
-
trunc = (flags & O_TRUNC);
flags &= ~O_TRUNC;
@@ -73,7 +90,7 @@ vflopenat(int dirfd, const char *path, int flags, va_list ap)
if ((fd = openat(dirfd, path, flags, mode)) == -1)
/* non-existent or no access */
return (-1);
- if (flock(fd, operation) == -1) {
+ if (lock_file(fd, flags) == -1) {
/* unsupported or interrupted */
serrno = errno;
(void)close(fd);