[hackers] [sbase] Initial implementation of flock(1) || sin

From: <git_AT_suckless.org>
Date: Wed, 7 Oct 2015 11:28:16 +0200 (CEST)

commit 2652dcfd6ce23f9efae3f96cda0becb873b676eb
Author: sin <sin_AT_2f30.org>
AuthorDate: Wed Oct 7 10:16:18 2015 +0100
Commit: sin <sin_AT_2f30.org>
CommitDate: Wed Oct 7 10:27:47 2015 +0100

    Initial implementation of flock(1)
    
    Very useful to prevent overlapping cron jobs amongst other things.

diff --git a/Makefile b/Makefile
index f99a038..c2d8266 100644
--- a/Makefile
+++ b/Makefile
_AT_@ -97,6 +97,7 @@ BIN =\
         expr\
         false\
         find\
+ flock\
         fold\
         getconf\
         grep\
diff --git a/flock.1 b/flock.1
new file mode 100644
index 0000000..344ec2e
--- /dev/null
+++ b/flock.1
_AT_@ -0,0 +1,29 @@
+.Dd October 7, 2015
+.Dt FLOCK 1
+.Os sbase
+.Sh NAME
+.Nm flock
+.Nd tool to manage locks on files
+.Sh SYNOPSIS
+.Nm
+.Op Fl nsux
+.Ar file
+.Ar cmd Op arg ...
+.Sh DESCRIPTION
+.Nm
+is used to manage advisory locks on open files. It is commonly used to prevent
+long running cron jobs from running in parallel. If
+.Ar file
+does not exist, it will be created.
+.Sh OPTIONS
+.Bl -tag -width Ds
+.It Fl n
+Set non-blocking mode on the lock. Fail immediately if the lock
+cannot be acquired.
+.It Fl s
+Acquire a shared lock.
+.It Fl u
+Release the lock.
+.It Fl x
+Acquire an exclusive lock. This is the default.
+.El
diff --git a/flock.c b/flock.c
new file mode 100644
index 0000000..f81a551
--- /dev/null
+++ b/flock.c
_AT_@ -0,0 +1,75 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/file.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "util.h"
+
+static void
+usage(void)
+{
+ eprintf("usage: %s [-nsux] file cmd [arg ...]\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int fd, status, savederrno, flags = LOCK_EX, nonblk = 0;
+ pid_t pid;
+
+ ARGBEGIN {
+ case 'n':
+ nonblk = LOCK_NB;
+ break;
+ case 's':
+ flags = LOCK_SH;
+ break;
+ case 'u':
+ flags = LOCK_UN;
+ break;
+ case 'x':
+ /* for compat */
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc < 2)
+ usage();
+
+ if ((fd = open(*argv, O_RDONLY | O_CREAT)) < 0)
+ eprintf("open %s:", *argv);
+
+ if (flock(fd, flags | nonblk)) {
+ if (nonblk && errno == EWOULDBLOCK)
+ return 1;
+ eprintf("flock:");
+ }
+
+ switch ((pid = fork())) {
+ case -1:
+ eprintf("fork:");
+ case 0:
+ argv++;
+ execvp(*argv, argv);
+ savederrno = errno;
+ weprintf("execvp %s:", *argv);
+ _exit(126 + (savederrno == ENOENT));
+ default:
+ break;
+ }
+ waitpid(pid, &status, 0);
+
+ if (WIFSIGNALED(status))
+ return 128 + WTERMSIG(status);
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+
+ if (close(fd) < 0)
+ eprintf("close:");
+
+ return 0;
+}
Received on Wed Oct 07 2015 - 11:28:16 CEST

This archive was generated by hypermail 2.3.0 : Wed Oct 07 2015 - 11:36:10 CEST