diff options
Diffstat (limited to 'sendmail/libsmutil/lockfile.c')
-rw-r--r-- | sendmail/libsmutil/lockfile.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/sendmail/libsmutil/lockfile.c b/sendmail/libsmutil/lockfile.c new file mode 100644 index 0000000..17d6237 --- /dev/null +++ b/sendmail/libsmutil/lockfile.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * All rights reserved. + * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the sendmail distribution. + * + */ + +#include <sendmail.h> + +SM_RCSID("@(#)$Id: lockfile.c,v 8.21 2003/11/10 22:57:38 ca Exp $") + + +/* +** LOCKFILE -- lock a file using flock or (shudder) fcntl locking +** +** Parameters: +** fd -- the file descriptor of the file. +** filename -- the file name (for error messages). [unused] +** ext -- the filename extension. [unused] +** type -- type of the lock. Bits can be: +** LOCK_EX -- exclusive lock. +** LOCK_NB -- non-blocking. +** LOCK_UN -- unlock. +** +** Returns: +** true if the lock was acquired. +** false otherwise. +*/ + +bool +lockfile(fd, filename, ext, type) + int fd; + char *filename; + char *ext; + int type; +{ +#if !HASFLOCK + int action; + struct flock lfd; + + memset(&lfd, '\0', sizeof lfd); + if (bitset(LOCK_UN, type)) + lfd.l_type = F_UNLCK; + else if (bitset(LOCK_EX, type)) + lfd.l_type = F_WRLCK; + else + lfd.l_type = F_RDLCK; + if (bitset(LOCK_NB, type)) + action = F_SETLK; + else + action = F_SETLKW; + + if (fcntl(fd, action, &lfd) >= 0) + return true; + + /* + ** On SunOS, if you are testing using -oQ/tmp/mqueue or + ** -oA/tmp/aliases or anything like that, and /tmp is mounted + ** as type "tmp" (that is, served from swap space), the + ** previous fcntl will fail with "Invalid argument" errors. + ** Since this is fairly common during testing, we will assume + ** that this indicates that the lock is successfully grabbed. + */ + + if (errno == EINVAL) + return true; + +#else /* !HASFLOCK */ + + if (flock(fd, type) >= 0) + return true; + +#endif /* !HASFLOCK */ + + return false; +} |