/*
* 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
* 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>
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);
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)) {