lockfile.c revision 266692
1/* 2 * Copyright (c) 1998-2001 Proofpoint, Inc. and its suppliers. 3 * All rights reserved. 4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5 * Copyright (c) 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * By using this file, you agree to the terms and conditions set 9 * forth in the LICENSE file which can be found at the top level of 10 * the sendmail distribution. 11 * 12 */ 13 14#include <sendmail.h> 15 16SM_RCSID("@(#)$Id: lockfile.c,v 8.22 2013-11-22 20:51:50 ca Exp $") 17 18 19/* 20** LOCKFILE -- lock a file using flock or (shudder) fcntl locking 21** 22** Parameters: 23** fd -- the file descriptor of the file. 24** filename -- the file name (for error messages). [unused] 25** ext -- the filename extension. [unused] 26** type -- type of the lock. Bits can be: 27** LOCK_EX -- exclusive lock. 28** LOCK_NB -- non-blocking. 29** LOCK_UN -- unlock. 30** 31** Returns: 32** true if the lock was acquired. 33** false otherwise. 34*/ 35 36bool 37lockfile(fd, filename, ext, type) 38 int fd; 39 char *filename; 40 char *ext; 41 int type; 42{ 43#if !HASFLOCK 44 int action; 45 struct flock lfd; 46 47 memset(&lfd, '\0', sizeof lfd); 48 if (bitset(LOCK_UN, type)) 49 lfd.l_type = F_UNLCK; 50 else if (bitset(LOCK_EX, type)) 51 lfd.l_type = F_WRLCK; 52 else 53 lfd.l_type = F_RDLCK; 54 if (bitset(LOCK_NB, type)) 55 action = F_SETLK; 56 else 57 action = F_SETLKW; 58 59 if (fcntl(fd, action, &lfd) >= 0) 60 return true; 61 62 /* 63 ** On SunOS, if you are testing using -oQ/tmp/mqueue or 64 ** -oA/tmp/aliases or anything like that, and /tmp is mounted 65 ** as type "tmp" (that is, served from swap space), the 66 ** previous fcntl will fail with "Invalid argument" errors. 67 ** Since this is fairly common during testing, we will assume 68 ** that this indicates that the lock is successfully grabbed. 69 */ 70 71 if (errno == EINVAL) 72 return true; 73 74#else /* !HASFLOCK */ 75 76 if (flock(fd, type) >= 0) 77 return true; 78 79#endif /* !HASFLOCK */ 80 81 return false; 82} 83