summaryrefslogtreecommitdiffstats
path: root/sendmail/libsmutil/lockfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'sendmail/libsmutil/lockfile.c')
-rw-r--r--sendmail/libsmutil/lockfile.c82
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;
+}
OpenPOWER on IntegriCloud