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