+static int lock_fd=-1;
+
+static int sighandler_flock_timeout_hit;
+static void sighandler_flock_timeout(int signo)
+{
+ sighandler_flock_timeout_hit=1;
+}
+
+static int lock_create(int lock_mode)
+{
+int retries=3;
+sighandler_t sighandler_alrm_orig;
+int flock_rc;
+
+ if (!opt_lock)
+ return 1;
+ /* Never drop the lock if the lock is already being held. */
+ if (lock_fd!=-1)
+ retries=-1;
+retry:
+ if (lock_fd==-1) {
+ if (-1==(lock_fd=open(opt_lock,O_CREAT|O_RDWR,0600)))
+ fatal("Error creating lock file \"%s\": %m",opt_lock);
+ }
+ sighandler_alrm_orig=signal(SIGALRM,sighandler_flock_timeout);
+ alarm(opt_start_command_timeout+FLOCK_TIMEOUT_OVER_START_TIMEOUT);
+ flock_rc=flock(lock_fd,lock_mode);
+ alarm(0);
+ signal(SIGALRM,sighandler_alrm_orig);
+ if (sighandler_flock_timeout_hit)
+ fatal("Timeout locking lock file \"%s\": %m",opt_lock);
+ if (flock_rc) {
+ if (lock_mode&LOCK_NB && errno==EWOULDBLOCK)
+ return 0;
+ fatal("Error locking lock file \"%s\": %m",opt_lock);
+ }
+ if (!access(opt_lock,R_OK|W_OK)) {
+ if (retries--<=0)
+ fatal("Racing for the lock file \"%s\", giving up",opt_lock);
+ if (close(lock_fd))
+ fatal("Error closing lock file \"%s\": %m",opt_lock);
+ lock_fd=-1;
+ goto retry;
+ }
+ return 1;
+}
+
+static void lock_touch(void)
+{
+ if (!opt_lock || lock_fd==-1)
+ return;
+ if (utime(opt_lock,NULL))
+ fatal("Error updating lock file \"%s\" timestamp: %m",opt_lock);
+}
+
+static void lock_close(void)
+{
+ if (lock_fd==-1)
+ return;
+ if (close(lock_fd))
+ fatal("Error closing lock file \"%s\": %m",opt_lock);
+ lock_fd=-1;
+}
+