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