chiark / gitweb /
with-lock-ex: provide -l
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 16 Nov 2016 15:21:51 +0000 (15:21 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 16 Nov 2016 15:21:51 +0000 (15:21 +0000)
cprogs/with-lock-ex.c
debian/changelog

index 1850d1f..2b7b45b 100644 (file)
@@ -1,12 +1,17 @@
 /*
  * File locker
  *
- * Usage: with-lock-ex -<mode> <lockfile> <command> <args>...
+ * Usage:
+ *  with-lock-ex -<mode> <lockfile> <command> <args>...
+ *  with-lock-ex -l      <lockfile>
  *
  * modes are
  *  w    wait for the lock
  *  f    fail if the lock cannot be acquired
  *  q    silently do nothing if the lock cannot be acquired
+ *  l    show who is waiting (print "none" or "read <pid>"
+ *         or "write <pid>"; lockfile opened for reading;
+ *         no command may be specified)
  *
  * with-lock-ex will open and lock the lockfile for writing and
  * then feed the remainder of its arguments to exec(2); when
@@ -17,7 +22,7 @@
  * compatibility with an earlier version).
  *
  * This file written by me, Ian Jackson, in 1993, 1994, 1995, 1996,
- * 1998, 1999.  I hereby place it in the public domain.
+ * 1998, 1999, 2016.  I hereby place it in the public domain.
  */
 
 #include <errno.h>
@@ -46,9 +51,13 @@ int main(int argc, char **argv) {
 
   if (argc >= 3 && !strcmp((p= strrchr(argv[0],'/')) ? ++p : argv[0], "with-lock")) {
     mode= 'f';
-  } else if (argc < 4 || argv[1][0] != '-' || argv[1][2] ||
-            ((mode= argv[1][1]) != 'w' && mode != 'q' && mode != 'f')) {
+  } else if (argc < 3 || argv[1][0] != '-' || argv[1][2] ||
+            ((mode= argv[1][1]) != 'w' && mode != 'q' && mode != 'f'
+             && mode != 'l') ||
+            (mode != 'l' && argc < 4) ||
+            (mode == 'l' && argc != 3)) {
     fputs("usage: with-lock-ex -w|-q|-f <lockfile> <command> <args>...\n"
+         "       with-lock-ex -l       <lockfile>\n"
          "       with-lock             <lockfile> <command> <args>...\n",
          stderr);
     exit(255);
@@ -60,21 +69,39 @@ int main(int argc, char **argv) {
   if (umask(um)==-1) fail("reset umask");
 
   for (;;) {
-  
-    fd= open(argv[1],O_RDWR|O_CREAT,0666&~(um|((um&0222)<<1)));
+
+    int openmode = mode=='l' ? O_RDONLY : O_RDWR|O_CREAT;
+
+    fd= open(argv[1],openmode,0666&~(um|((um&0222)<<1)));
     if (fd<0) fail(argv[1]);
   
     for (;;) {
       fl.l_type= F_WRLCK;
       fl.l_whence= SEEK_SET;
       fl.l_start= 0;
-      fl.l_len= 1;
-      if (fcntl(fd, mode=='w' ? F_SETLKW : F_SETLK, &fl) != -1) break;
+      fl.l_len= mode=='l' ? 0 : 1;
+      if (fcntl(fd,
+               mode=='l' ? F_GETLK :
+               mode=='w' ? F_SETLKW :
+               F_SETLK,
+               &fl) != -1) break;
       if (mode=='q' &&
          (errno == EAGAIN || errno == EWOULDBLOCK || errno == EBUSY))
        exit(0);
       if (errno != EINTR) fail("could not acquire lock");
     }
+    if (mode=='l') {
+      if (fl.l_pid) {
+       printf("%s %lu\n",
+              fl.l_type == F_WRLCK ? "write" :
+              fl.l_type == F_RDLCK ? "read" : "unknown",
+              (unsigned long)fl.l_pid);
+      } else {
+       printf("none\n");
+      }
+      if (ferror(stdout)) fail("print to stdout\n");
+      exit(0);
+    }
 
     if (fstat(fd, &fstab)) fail("could not fstat lock fd");
     if (stat(argv[1], &stab)) {
index db69af0..0b673ab 100644 (file)
@@ -1,6 +1,6 @@
 chiark-utils (5.0.1~) unstable; urgency=medium
 
-  * 
+  * with-lock-ex: provide -l
 
  --