1*cf1d77f7Schristos /*	$NetBSD: lockf.c,v 1.3 2021/08/14 16:14:58 christos Exp $	*/
24e6df137Slukem 
333197c6aStron /* $OpenLDAP$ */
42de962bdSlukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
52de962bdSlukem  *
6*cf1d77f7Schristos  * Copyright 1998-2021 The OpenLDAP Foundation.
72de962bdSlukem  * All rights reserved.
82de962bdSlukem  *
92de962bdSlukem  * Redistribution and use in source and binary forms, with or without
102de962bdSlukem  * modification, are permitted only as authorized by the OpenLDAP
112de962bdSlukem  * Public License.
122de962bdSlukem  *
132de962bdSlukem  * A copy of this license is available in the file LICENSE in the
142de962bdSlukem  * top-level directory of the distribution or, alternatively, at
152de962bdSlukem  * <http://www.OpenLDAP.org/license.html>.
162de962bdSlukem  */
172de962bdSlukem 
182de962bdSlukem /*
192de962bdSlukem  * File Locking Routines
202de962bdSlukem  *
212de962bdSlukem  * Implementations (in order of preference)
222de962bdSlukem  *	- lockf
232de962bdSlukem  *	- fcntl
242de962bdSlukem  *  - flock
252de962bdSlukem  *
262de962bdSlukem  * Other implementations will be added as needed.
272de962bdSlukem  *
282de962bdSlukem  * NOTE: lutil_lockf() MUST block until an exclusive lock is acquired.
292de962bdSlukem  */
302de962bdSlukem 
318bd9f7cdSchristos #include <sys/cdefs.h>
32*cf1d77f7Schristos __RCSID("$NetBSD: lockf.c,v 1.3 2021/08/14 16:14:58 christos Exp $");
338bd9f7cdSchristos 
342de962bdSlukem #include "portable.h"
352de962bdSlukem 
362de962bdSlukem #include <stdio.h>
372de962bdSlukem #include <ac/unistd.h>
382de962bdSlukem 
392de962bdSlukem #undef LOCK_API
402de962bdSlukem 
412de962bdSlukem #if defined(HAVE_LOCKF) && defined(F_LOCK)
422de962bdSlukem #	define USE_LOCKF 1
432de962bdSlukem #	define LOCK_API	"lockf"
442de962bdSlukem #endif
452de962bdSlukem 
462de962bdSlukem #if !defined(LOCK_API) && defined(HAVE_FCNTL)
472de962bdSlukem #	ifdef HAVE_FCNTL_H
482de962bdSlukem #		include <fcntl.h>
492de962bdSlukem #	endif
502de962bdSlukem #	ifdef F_WRLCK
512de962bdSlukem #		define USE_FCNTL 1
522de962bdSlukem #		define LOCK_API	"fcntl"
532de962bdSlukem #	endif
542de962bdSlukem #endif
552de962bdSlukem 
562de962bdSlukem #if !defined(LOCK_API) && defined(HAVE_FLOCK)
572de962bdSlukem #	ifdef HAVE_SYS_FILE_H
582de962bdSlukem #		include <sys/file.h>
592de962bdSlukem #	endif
602de962bdSlukem #	define USE_FLOCK 1
612de962bdSlukem #	define LOCK_API	"flock"
622de962bdSlukem #endif
632de962bdSlukem 
642de962bdSlukem #if !defined(USE_LOCKF) && !defined(USE_FCNTL) && !defined(USE_FLOCK)
lutil_lockf(int fd)652de962bdSlukem int lutil_lockf ( int fd ) {
662de962bdSlukem     fd = fd;
672de962bdSlukem     return 0;
682de962bdSlukem }
692de962bdSlukem 
lutil_unlockf(int fd)702de962bdSlukem int lutil_unlockf ( int fd ) {
712de962bdSlukem     fd = fd;
722de962bdSlukem     return 0;
732de962bdSlukem }
742de962bdSlukem #endif
752de962bdSlukem 
762de962bdSlukem #ifdef USE_LOCKF
lutil_lockf(int fd)772de962bdSlukem int lutil_lockf ( int fd ) {
782de962bdSlukem 	/* use F_LOCK instead of F_TLOCK, ie: block */
792de962bdSlukem 	return lockf( fd, F_LOCK, 0 );
802de962bdSlukem }
812de962bdSlukem 
lutil_unlockf(int fd)822de962bdSlukem int lutil_unlockf ( int fd ) {
832de962bdSlukem 	return lockf( fd, F_ULOCK, 0 );
842de962bdSlukem }
852de962bdSlukem #endif
862de962bdSlukem 
872de962bdSlukem #ifdef USE_FCNTL
lutil_lockf(int fd)882de962bdSlukem int lutil_lockf ( int fd ) {
892de962bdSlukem 	struct flock file_lock;
902de962bdSlukem 
912de962bdSlukem 	memset( &file_lock, '\0', sizeof( file_lock ) );
922de962bdSlukem 	file_lock.l_type = F_WRLCK;
932de962bdSlukem 	file_lock.l_whence = SEEK_SET;
942de962bdSlukem 	file_lock.l_start = 0;
952de962bdSlukem 	file_lock.l_len = 0;
962de962bdSlukem 
972de962bdSlukem 	/* use F_SETLKW instead of F_SETLK, ie: block */
982de962bdSlukem 	return( fcntl( fd, F_SETLKW, &file_lock ) );
992de962bdSlukem }
1002de962bdSlukem 
lutil_unlockf(int fd)1012de962bdSlukem int lutil_unlockf ( int fd ) {
1022de962bdSlukem 	struct flock file_lock;
1032de962bdSlukem 
1042de962bdSlukem 	memset( &file_lock, '\0', sizeof( file_lock ) );
1052de962bdSlukem 	file_lock.l_type = F_UNLCK;
1062de962bdSlukem 	file_lock.l_whence = SEEK_SET;
1072de962bdSlukem 	file_lock.l_start = 0;
1082de962bdSlukem 	file_lock.l_len = 0;
1092de962bdSlukem 
1102de962bdSlukem 	return( fcntl ( fd, F_SETLKW, &file_lock ) );
1112de962bdSlukem }
1122de962bdSlukem #endif
1132de962bdSlukem 
1142de962bdSlukem #ifdef USE_FLOCK
lutil_lockf(int fd)1152de962bdSlukem int lutil_lockf ( int fd ) {
1162de962bdSlukem 	/* use LOCK_EX instead of LOCK_EX|LOCK_NB, ie: block */
1172de962bdSlukem 	return flock( fd, LOCK_EX );
1182de962bdSlukem }
1192de962bdSlukem 
lutil_unlockf(int fd)1202de962bdSlukem int lutil_unlockf ( int fd ) {
1212de962bdSlukem 	return flock( fd, LOCK_UN );
1222de962bdSlukem }
1232de962bdSlukem #endif
124