[hackers] [sbase] Initial implementation of flock(1) || sin
 
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