4 * Usage: with-lock-ex -<mode> <lockfile> <command> <args>...
8 * f fail if the lock cannot be acquired
9 * q silently do nothing if the lock cannot be acquired
11 * with-lock-ex will open and lock the lockfile for writing and
12 * then feed the remainder of its arguments to exec(2); when
13 * that process terminates the fd will be closed and the file
14 * unlocked automatically by the kernel.
16 * If invoked as with-lock, behaves like with-lock-ex -f (for backward
17 * compatibility with an earlier version).
19 * This file written by me, Ian Jackson, in 1993, 1994, 1995, 1996,
20 * 1998, 1999. I hereby place it in the public domain.
31 static const char *cmd;
33 static void fail(const char *why) __attribute__((noreturn));
35 static void fail(const char *why) {
36 fprintf(stderr,"with-lock-ex %s: %s: %s\n",cmd,why,strerror(errno));
40 int main(int argc, char **argv) {
46 if (argc >= 3 && !strcmp((p= strrchr(argv[0],'/')) ? ++p : argv[0], "with-lock")) {
48 } else if (argc < 4 || argv[1][0] != '-' || argv[1][2] ||
49 ((mode= argv[1][1]) != 'w' && mode != 'q' && mode != 'f')) {
50 fputs("usage: with-lock-ex -w|-q|-f <lockfile> <command> <args>...\n"
51 " with-lock <lockfile> <command> <args>...\n",
58 um= umask(0777); if (um==-1) fail("find umask");
59 if (umask(um)==-1) fail("reset umask");
61 fd= open(argv[1],O_RDWR|O_CREAT,0666&~(um|((um&0222)<<1))); if (fd<0) fail(argv[1]);
65 fl.l_whence= SEEK_SET;
68 if (fcntl(fd, mode=='w' ? F_SETLKW : F_SETLK, &fl) != -1) break;
69 if (mode=='q' && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EBUSY)) exit(0);
70 if (errno != EINTR) fail("could not acquire lock");
73 cloexec= fcntl(fd, F_GETFD); if (cloexec==-1) fail("fcntl F_GETFD");
75 if (fcntl(fd, F_SETFD, cloexec)==-1) fail("fcntl F_SETFD");
78 fail("unable to execute command");