1/*	$NetBSD$	*/
2
3/* OpenLDAP: pkg/ldap/libraries/liblutil/lockf.c,v 1.15.2.5 2010/04/13 20:23:06 kurt Exp */
4/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 *
6 * Copyright 1998-2010 The OpenLDAP Foundation.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
11 * Public License.
12 *
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
16 */
17
18/*
19 * File Locking Routines
20 *
21 * Implementations (in order of preference)
22 *	- lockf
23 *	- fcntl
24 *  - flock
25 *
26 * Other implementations will be added as needed.
27 *
28 * NOTE: lutil_lockf() MUST block until an exclusive lock is acquired.
29 */
30
31#include "portable.h"
32
33#include <stdio.h>
34#include <ac/unistd.h>
35
36#undef LOCK_API
37
38#if defined(HAVE_LOCKF) && defined(F_LOCK)
39#	define USE_LOCKF 1
40#	define LOCK_API	"lockf"
41#endif
42
43#if !defined(LOCK_API) && defined(HAVE_FCNTL)
44#	ifdef HAVE_FCNTL_H
45#		include <fcntl.h>
46#	endif
47#	ifdef F_WRLCK
48#		define USE_FCNTL 1
49#		define LOCK_API	"fcntl"
50#	endif
51#endif
52
53#if !defined(LOCK_API) && defined(HAVE_FLOCK)
54#	ifdef HAVE_SYS_FILE_H
55#		include <sys/file.h>
56#	endif
57#	define USE_FLOCK 1
58#	define LOCK_API	"flock"
59#endif
60
61#if !defined(USE_LOCKF) && !defined(USE_FCNTL) && !defined(USE_FLOCK)
62int lutil_lockf ( int fd ) {
63    fd = fd;
64    return 0;
65}
66
67int lutil_unlockf ( int fd ) {
68    fd = fd;
69    return 0;
70}
71#endif
72
73#ifdef USE_LOCKF
74int lutil_lockf ( int fd ) {
75	/* use F_LOCK instead of F_TLOCK, ie: block */
76	return lockf( fd, F_LOCK, 0 );
77}
78
79int lutil_unlockf ( int fd ) {
80	return lockf( fd, F_ULOCK, 0 );
81}
82#endif
83
84#ifdef USE_FCNTL
85int lutil_lockf ( int fd ) {
86	struct flock file_lock;
87
88	memset( &file_lock, '\0', sizeof( file_lock ) );
89	file_lock.l_type = F_WRLCK;
90	file_lock.l_whence = SEEK_SET;
91	file_lock.l_start = 0;
92	file_lock.l_len = 0;
93
94	/* use F_SETLKW instead of F_SETLK, ie: block */
95	return( fcntl( fd, F_SETLKW, &file_lock ) );
96}
97
98int lutil_unlockf ( int fd ) {
99	struct flock file_lock;
100
101	memset( &file_lock, '\0', sizeof( file_lock ) );
102	file_lock.l_type = F_UNLCK;
103	file_lock.l_whence = SEEK_SET;
104	file_lock.l_start = 0;
105	file_lock.l_len = 0;
106
107	return( fcntl ( fd, F_SETLKW, &file_lock ) );
108}
109#endif
110
111#ifdef USE_FLOCK
112int lutil_lockf ( int fd ) {
113	/* use LOCK_EX instead of LOCK_EX|LOCK_NB, ie: block */
114	return flock( fd, LOCK_EX );
115}
116
117int lutil_unlockf ( int fd ) {
118	return flock( fd, LOCK_UN );
119}
120#endif
121