summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2003-03-17 15:10:54 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2003-03-17 15:10:54 (GMT)
commit8fae5bde117ac59f3c757a7dfe708444c969fbd2 (patch)
treee961bc2e7c67bac30f353dfb76f1bc8b2718ef11
parent65a64f0883745ae1b6776cbf4788dca7db9a366e (diff)
downloadflock-8fae5bde117ac59f3c757a7dfe708444c969fbd2.zip
flock-8fae5bde117ac59f3c757a7dfe708444c969fbd2.tar.gz
flock-8fae5bde117ac59f3c757a7dfe708444c969fbd2.tar.bz2
flock-8fae5bde117ac59f3c757a7dfe708444c969fbd2.tar.xz
flock(1) utility
-rw-r--r--flock.186
-rw-r--r--flock.c92
2 files changed, 178 insertions, 0 deletions
diff --git a/flock.1 b/flock.1
new file mode 100644
index 0000000..8b0d600
--- /dev/null
+++ b/flock.1
@@ -0,0 +1,86 @@
+.\" $Id$
+.\" -----------------------------------------------------------------------
+.\"
+.\" Copyright 2003 H. Peter Anvin - All Rights Reserved
+.\"
+.\" Permission is hereby granted, free of charge, to any person
+.\" obtaining a copy of this software and associated documentation
+.\" files (the "Software"), to deal in the Software without
+.\" restriction, including without limitation the rights to use,
+.\" copy, modify, merge, publish, distribute, sublicense, and/or
+.\" sell copies of the Software, and to permit persons to whom
+.\" the Software is furnished to do so, subject to the following
+.\" conditions:
+.\"
+.\" The above copyright notice and this permission notice shall
+.\" be included in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+.\" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+.\" OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+.\" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+.\" HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+.\" WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+.\" FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\" OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" -----------------------------------------------------------------------
+.TH FLOCK "1" "17 Mar 2003" "flock utility" "H. Peter Anvin"
+.SH NAME
+flock \- Manage locks from shell scripts
+.SH SYNOPSIS
+\fBflock\fP [\fIOPTIONS\fR] FD
+.SH DESCRIPTION
+.PP
+This utility manages
+.BR flock (2)
+locks from within shell scripts. It is usually used in something
+similar to the following manner:
+.PP
+\fC(
+.br
+ flock -s 200
+.br
+ # ... commands executed under lock ...
+.br
+) 200>/var/lock/mylockfile\fP
+.PP
+The mode used to open the file doesn't matter to \fBflock\fP; using
+\fC>\fP or \fP>>\fP allows the lockfile to be created if it does not
+already exist, however, write permission is required; using \fC<\fP
+requires that the file already exists but only read permission is
+required.
+.PP
+By default, if the lock cannot be immediately acquired, \fBflock\fP
+waits until the lock is available.
+.SH OPTIONS
+.TP
+\fB\-s\fP, \fB\-\-shared\fP
+Obtain a shared lock, sometimes called a read lock.
+.TP
+\fB\-x\fP, \fB\-\-exclusive\fP
+Obtain an exclusive lock, sometimes called a write lock. This is the
+default.
+.TP
+\fB\-u\fP, \fB\-\-unlock\fP
+Drop a lock. This is usually not required, since a lock is
+automatically dropped when the file is closed. However, it may be
+required in special cases, for example if the enclosed command group
+may have forked a background process which should not be holding the
+lock.
+.TP
+\fB\-n\fP, \fB\-\-nonblock\fP
+Fail (with an exit code of 1) rather than wait if the lock cannot be
+immediately acquired.
+.TP
+\fB\-h\fP, \fB\-\-help\fP
+Print a help message.
+.SH AUTHOR
+Written by H. Peter Anvin <hpa@zytor.com>.
+.SH COPYRIGHT
+Copyright \(co 2003 H. Peter Anvin.
+.br
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+.SH "SEE ALSO"
+.BR flock (2)
diff --git a/flock.c b/flock.c
new file mode 100644
index 0000000..99b4f20
--- /dev/null
+++ b/flock.c
@@ -0,0 +1,92 @@
+/*
+ * flock.c - Hold a lock file and spawn a program
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <sysexits.h>
+#include <sys/file.h>
+
+const struct option long_options[] = {
+ { "shared", 0, NULL, 's' },
+ { "exclusive", 0, NULL, 'x' },
+ { "unlock", 0, NULL, 'u' },
+ { "nonblocking", 0, NULL, 'n' },
+ { "nb", 0, NULL, 'n' },
+ { "help", 0, NULL, 'h' },
+ { 0, 0, 0, 0 }
+};
+
+const char *program;
+
+void usage(int ex)
+{
+ fprintf(stderr, "Usage: %s [options] fd#\n",
+ " -s --shared Get a shared lock\n"
+ " -e --exclusive Get an exclusive lock\n"
+ " -u --unlock Remove a lock\n"
+ " -n --nonblock Fail rather than wait\n"
+ " -h --help Display this text\n",
+ program);
+ exit(ex);
+}
+
+
+int main(int argc, char *argv[])
+{
+ int type = LOCK_EX;
+ int block = 0;
+ int fd;
+ int opt, ix;
+ int err;
+ char *eon;
+
+ program = argv[0];
+
+ if ( argc < 2 )
+ usage(EX_USAGE);
+
+ while ( (opt = getopt_long(argc, argv, "sexnuh", long_options, &ix)) != EOF ) {
+ switch(opt) {
+ case 's':
+ type = LOCK_SH;
+ break;
+ case 'e':
+ case 'x':
+ type = LOCK_EX;
+ break;
+ case 'u':
+ type = LOCK_UN;
+ break;
+ case 'n':
+ block = LOCK_NB;
+ break;
+ default:
+ usage(EX_USAGE);
+ break;
+ }
+ }
+
+ fd = (int)strtol(argv[optind], &eon, 10);
+ if ( *eon || !argv[optind] ) {
+ fprintf(stderr, "%s: bad number: %s\n", program, argv[optind]);
+ exit(EX_USAGE);
+ }
+
+ while ( flock(fd, type|block) ) {
+ switch( (err = errno) ) {
+ case EWOULDBLOCK: /* -n option set and failed to lock */
+ exit(1);
+ case EINTR: /* Interrupted, try again */
+ continue;
+ default: /* Other errors */
+ fprintf(stderr, "%s: %d: %s\n", program, fd, strerror(err));
+ exit((err == ENOLCK||err == ENOMEM) ? EX_OSERR : EX_DATAERR);
+ }
+ }
+
+ return 0; /* If we get here, we were successful */
+}