From 3d0cc8d2ed098b7ef300f46458c8b33d029d0429 Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 19 Jul 2001 20:23:26 +0000 Subject: [PATCH 1/1] Found with-lock-ex.c on jura. --- misc/with-lock-ex.c | 95 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 misc/with-lock-ex.c diff --git a/misc/with-lock-ex.c b/misc/with-lock-ex.c new file mode 100644 index 0000000..1850d1f --- /dev/null +++ b/misc/with-lock-ex.c @@ -0,0 +1,95 @@ +/* + * File locker + * + * Usage: with-lock-ex - ... + * + * 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 + * + * with-lock-ex will open and lock the lockfile for writing and + * then feed the remainder of its arguments to exec(2); when + * that process terminates the fd will be closed and the file + * unlocked automatically by the kernel. + * + * If invoked as with-lock, behaves like with-lock-ex -f (for backward + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +static const char *cmd; + +static void fail(const char *why) __attribute__((noreturn)); + +static void fail(const char *why) { + fprintf(stderr,"with-lock-ex %s: %s: %s\n",cmd,why,strerror(errno)); + exit(255); +} + +int main(int argc, char **argv) { + int fd, mode, um; + struct stat stab, fstab; + long cloexec; + struct flock fl; + const char *p; + + 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')) { + fputs("usage: with-lock-ex -w|-q|-f ...\n" + " with-lock ...\n", + stderr); + exit(255); + } else { + argv++; argc--; + } + cmd= argv[2]; + um= umask(0777); if (um==-1) fail("find umask"); + if (umask(um)==-1) fail("reset umask"); + + for (;;) { + + fd= open(argv[1],O_RDWR|O_CREAT,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; + if (mode=='q' && + (errno == EAGAIN || errno == EWOULDBLOCK || errno == EBUSY)) + exit(0); + if (errno != EINTR) fail("could not acquire lock"); + } + + if (fstat(fd, &fstab)) fail("could not fstat lock fd"); + if (stat(argv[1], &stab)) { + if (errno != ENOENT) fail("could not stat lockfile"); + } else { + if (stab.st_dev == fstab.st_dev && + stab.st_ino == fstab.st_ino) break; + } + close(fd); + } + + cloexec= fcntl(fd, F_GETFD); if (cloexec==-1) fail("fcntl F_GETFD"); + cloexec &= ~1; + if (fcntl(fd, F_SETFD, cloexec)==-1) fail("fcntl F_SETFD"); + + execvp(cmd,argv+2); + fail("unable to execute command"); +} -- 2.30.2