1 /* $NetBSD: lockf.c,v 1.2 2020/08/11 13:15:39 christos Exp $ */ 2 3 /* $OpenLDAP$ */ 4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 1998-2020 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.2 2020/08/11 13:15:39 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) 65 int lutil_lockf ( int fd ) { 66 fd = fd; 67 return 0; 68 } 69 70 int lutil_unlockf ( int fd ) { 71 fd = fd; 72 return 0; 73 } 74 #endif 75 76 #ifdef USE_LOCKF 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 82 int lutil_unlockf ( int fd ) { 83 return lockf( fd, F_ULOCK, 0 ); 84 } 85 #endif 86 87 #ifdef USE_FCNTL 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 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 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 120 int lutil_unlockf ( int fd ) { 121 return flock( fd, LOCK_UN ); 122 } 123 #endif 124