summaryrefslogtreecommitdiff
path: root/src/port/lockf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/port/lockf.c')
-rw-r--r--src/port/lockf.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/port/lockf.c b/src/port/lockf.c
new file mode 100644
index 0000000..09c613e
--- /dev/null
+++ b/src/port/lockf.c
@@ -0,0 +1,62 @@
+#include "lockf.h"
+
+#include "string.h" /* for memset */
+#include "unistd.h" /* for getpid */
+
+#if !defined HAVE_LOCKF
+
+#include <sys/types.h> /* for off_t */
+#include <errno.h> /* for errno */
+
+int lockf( int fd, int cmd, off_t len ) {
+ struct flock fl;
+
+ memset( (char *)&fl, 0, sizeof( fl ) );
+ /* lockf is always relative to the current file position. */
+ fl.l_whence = SEEK_CUR;
+ fl.l_start = 0;
+ fl.l_len = len;
+
+ errno = 0;
+
+ switch( cmd ) {
+ case F_TEST:
+ fl.l_type = F_RDLCK;
+ if( fcntl( fd, F_GETLK, &fl ) < 0 ) {
+ return -1;
+ }
+ if( fl.l_type == F_UNLCK ||
+ fl.l_pid == getpid( ) ) {
+ return 0;
+ }
+ errno = EACCES;
+ return -1;
+
+ case F_ULOCK:
+ fl.l_type = F_UNLCK;
+ cmd = F_SETLK;
+ break;
+
+ case F_LOCK:
+ fl.l_type = F_WRLCK;
+ cmd = F_SETLKW;
+ break;
+
+ case F_TLOCK:
+ fl.l_type = F_WRLCK;
+ cmd = F_SETLK;
+ break;
+
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ return fcntl( fd, cmd, &fl );
+}
+
+#else
+
+extern int dummy; /* prevent ISO C forbids an empty source file' warning */
+
+#endif /* !defined HAVE_LOCKF */