164562Sgshapiro/* 290792Sgshapiro * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. 364562Sgshapiro * All rights reserved. 464562Sgshapiro * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 564562Sgshapiro * Copyright (c) 1988, 1993 664562Sgshapiro * The Regents of the University of California. All rights reserved. 764562Sgshapiro * 864562Sgshapiro * By using this file, you agree to the terms and conditions set 964562Sgshapiro * forth in the LICENSE file which can be found at the top level of 1064562Sgshapiro * the sendmail distribution. 1164562Sgshapiro * 1264562Sgshapiro */ 1364562Sgshapiro 1464562Sgshapiro#include <sendmail.h> 1564562Sgshapiro 16132943SgshapiroSM_RCSID("@(#)$Id: lockfile.c,v 8.21 2003/11/10 22:57:38 ca Exp $") 1790792Sgshapiro 1890792Sgshapiro 1990792Sgshapiro/* 2064562Sgshapiro** LOCKFILE -- lock a file using flock or (shudder) fcntl locking 2164562Sgshapiro** 2264562Sgshapiro** Parameters: 2364562Sgshapiro** fd -- the file descriptor of the file. 2464562Sgshapiro** filename -- the file name (for error messages). [unused] 2564562Sgshapiro** ext -- the filename extension. [unused] 2664562Sgshapiro** type -- type of the lock. Bits can be: 2764562Sgshapiro** LOCK_EX -- exclusive lock. 2864562Sgshapiro** LOCK_NB -- non-blocking. 2971345Sgshapiro** LOCK_UN -- unlock. 3064562Sgshapiro** 3164562Sgshapiro** Returns: 3290792Sgshapiro** true if the lock was acquired. 3390792Sgshapiro** false otherwise. 3464562Sgshapiro*/ 3564562Sgshapiro 3664562Sgshapirobool 3764562Sgshapirolockfile(fd, filename, ext, type) 3864562Sgshapiro int fd; 3964562Sgshapiro char *filename; 4064562Sgshapiro char *ext; 4164562Sgshapiro int type; 4264562Sgshapiro{ 4364562Sgshapiro#if !HASFLOCK 4464562Sgshapiro int action; 4564562Sgshapiro struct flock lfd; 4664562Sgshapiro 4764562Sgshapiro memset(&lfd, '\0', sizeof lfd); 4864562Sgshapiro if (bitset(LOCK_UN, type)) 4964562Sgshapiro lfd.l_type = F_UNLCK; 5064562Sgshapiro else if (bitset(LOCK_EX, type)) 5164562Sgshapiro lfd.l_type = F_WRLCK; 5264562Sgshapiro else 5364562Sgshapiro lfd.l_type = F_RDLCK; 5464562Sgshapiro if (bitset(LOCK_NB, type)) 5564562Sgshapiro action = F_SETLK; 5664562Sgshapiro else 5764562Sgshapiro action = F_SETLKW; 5864562Sgshapiro 5964562Sgshapiro if (fcntl(fd, action, &lfd) >= 0) 6090792Sgshapiro return true; 6164562Sgshapiro 6264562Sgshapiro /* 6364562Sgshapiro ** On SunOS, if you are testing using -oQ/tmp/mqueue or 6464562Sgshapiro ** -oA/tmp/aliases or anything like that, and /tmp is mounted 6564562Sgshapiro ** as type "tmp" (that is, served from swap space), the 6664562Sgshapiro ** previous fcntl will fail with "Invalid argument" errors. 6764562Sgshapiro ** Since this is fairly common during testing, we will assume 6864562Sgshapiro ** that this indicates that the lock is successfully grabbed. 6964562Sgshapiro */ 7064562Sgshapiro 7164562Sgshapiro if (errno == EINVAL) 7290792Sgshapiro return true; 7364562Sgshapiro 7464562Sgshapiro#else /* !HASFLOCK */ 7564562Sgshapiro 7664562Sgshapiro if (flock(fd, type) >= 0) 7790792Sgshapiro return true; 7864562Sgshapiro 7964562Sgshapiro#endif /* !HASFLOCK */ 8064562Sgshapiro 8190792Sgshapiro return false; 8264562Sgshapiro} 83