1 /* 2 * Copyright (c) 1998-2001 Sendmail, 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 #pragma ident "%Z%%M% %I% %E% SMI" 15 16 #include <sendmail.h> 17 18 SM_RCSID("@(#)$Id: lockfile.c,v 8.21 2003/11/10 22:57:38 ca Exp $") 19 20 21 /* 22 ** LOCKFILE -- lock a file using flock or (shudder) fcntl locking 23 ** 24 ** Parameters: 25 ** fd -- the file descriptor of the file. 26 ** filename -- the file name (for error messages). [unused] 27 ** ext -- the filename extension. [unused] 28 ** type -- type of the lock. Bits can be: 29 ** LOCK_EX -- exclusive lock. 30 ** LOCK_NB -- non-blocking. 31 ** LOCK_UN -- unlock. 32 ** 33 ** Returns: 34 ** true if the lock was acquired. 35 ** false otherwise. 36 */ 37 38 bool 39 lockfile(fd, filename, ext, type) 40 int fd; 41 char *filename; 42 char *ext; 43 int type; 44 { 45 #if !HASFLOCK 46 int action; 47 struct flock lfd; 48 49 memset(&lfd, '\0', sizeof lfd); 50 if (bitset(LOCK_UN, type)) 51 lfd.l_type = F_UNLCK; 52 else if (bitset(LOCK_EX, type)) 53 lfd.l_type = F_WRLCK; 54 else 55 lfd.l_type = F_RDLCK; 56 if (bitset(LOCK_NB, type)) 57 action = F_SETLK; 58 else 59 action = F_SETLKW; 60 61 if (fcntl(fd, action, &lfd) >= 0) 62 return true; 63 64 /* 65 ** On SunOS, if you are testing using -oQ/tmp/mqueue or 66 ** -oA/tmp/aliases or anything like that, and /tmp is mounted 67 ** as type "tmp" (that is, served from swap space), the 68 ** previous fcntl will fail with "Invalid argument" errors. 69 ** Since this is fairly common during testing, we will assume 70 ** that this indicates that the lock is successfully grabbed. 71 */ 72 73 if (errno == EINVAL) 74 return true; 75 76 #else /* !HASFLOCK */ 77 78 if (flock(fd, type) >= 0) 79 return true; 80 81 #endif /* !HASFLOCK */ 82 83 return false; 84 } 85