1 /*	$NetBSD: lockf.c,v 1.3 2021/08/14 16:14:58 christos Exp $	*/
2 
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5  *
6  * Copyright 1998-2021 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 <sys/cdefs.h>
32 __RCSID("$NetBSD: lockf.c,v 1.3 2021/08/14 16:14:58 christos Exp $");
33 
34 #include "portable.h"
35 
36 #include <stdio.h>
37 #include <ac/unistd.h>
38 
39 #undef LOCK_API
40 
41 #if defined(HAVE_LOCKF) && defined(F_LOCK)
42 #	define USE_LOCKF 1
43 #	define LOCK_API	"lockf"
44 #endif
45 
46 #if !defined(LOCK_API) && defined(HAVE_FCNTL)
47 #	ifdef HAVE_FCNTL_H
48 #		include <fcntl.h>
49 #	endif
50 #	ifdef F_WRLCK
51 #		define USE_FCNTL 1
52 #		define LOCK_API	"fcntl"
53 #	endif
54 #endif
55 
56 #if !defined(LOCK_API) && defined(HAVE_FLOCK)
57 #	ifdef HAVE_SYS_FILE_H
58 #		include <sys/file.h>
59 #	endif
60 #	define USE_FLOCK 1
61 #	define LOCK_API	"flock"
62 #endif
63 
64 #if !defined(USE_LOCKF) && !defined(USE_FCNTL) && !defined(USE_FLOCK)
lutil_lockf(int fd)65 int lutil_lockf ( int fd ) {
66     fd = fd;
67     return 0;
68 }
69 
lutil_unlockf(int fd)70 int lutil_unlockf ( int fd ) {
71     fd = fd;
72     return 0;
73 }
74 #endif
75 
76 #ifdef USE_LOCKF
lutil_lockf(int fd)77 int lutil_lockf ( int fd ) {
78 	/* use F_LOCK instead of F_TLOCK, ie: block */
79 	return lockf( fd, F_LOCK, 0 );
80 }
81 
lutil_unlockf(int fd)82 int lutil_unlockf ( int fd ) {
83 	return lockf( fd, F_ULOCK, 0 );
84 }
85 #endif
86 
87 #ifdef USE_FCNTL
lutil_lockf(int fd)88 int lutil_lockf ( int fd ) {
89 	struct flock file_lock;
90 
91 	memset( &file_lock, '\0', sizeof( file_lock ) );
92 	file_lock.l_type = F_WRLCK;
93 	file_lock.l_whence = SEEK_SET;
94 	file_lock.l_start = 0;
95 	file_lock.l_len = 0;
96 
97 	/* use F_SETLKW instead of F_SETLK, ie: block */
98 	return( fcntl( fd, F_SETLKW, &file_lock ) );
99 }
100 
lutil_unlockf(int fd)101 int lutil_unlockf ( int fd ) {
102 	struct flock file_lock;
103 
104 	memset( &file_lock, '\0', sizeof( file_lock ) );
105 	file_lock.l_type = F_UNLCK;
106 	file_lock.l_whence = SEEK_SET;
107 	file_lock.l_start = 0;
108 	file_lock.l_len = 0;
109 
110 	return( fcntl ( fd, F_SETLKW, &file_lock ) );
111 }
112 #endif
113 
114 #ifdef USE_FLOCK
lutil_lockf(int fd)115 int lutil_lockf ( int fd ) {
116 	/* use LOCK_EX instead of LOCK_EX|LOCK_NB, ie: block */
117 	return flock( fd, LOCK_EX );
118 }
119 
lutil_unlockf(int fd)120 int lutil_unlockf ( int fd ) {
121 	return flock( fd, LOCK_UN );
122 }
123 #endif
124