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