+/* It will never create the lock file if: lock_mode&LOCK_NB */
+static enum lock_create_rc lock_create(int lock_mode)
+{
+int retries=3;
+sighandler_t sighandler_alrm_orig;
+int flock_rc;
+
+ if (!opt_lock)
+ return LOCK_CREATE_NO_LOCK_FILENAME;
+ /* 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_RDWR | (lock_mode&LOCK_NB ? 0 : O_CREAT),
+ 0600))) {
+ if (errno==ENOENT && lock_mode&LOCK_NB)
+ return LOCK_CREATE_FILE_NOT_FOUND;
+ 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 LOCK_CREATE_ALREADY_LOCKED;
+ 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 LOCK_CREATE_MYSELF_LOCKED;
+}
+
+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 || !opt_lock)
+ return;
+ /* It should not be needed but some stale locks were seen on:
+ * White Box Linux kernel-smp-2.6.9-5.0.5.EL
+ */
+ if (flock(lock_fd,LOCK_UN|LOCK_NB))
+ fatal("Error unlocking lock file \"%s\": %m",opt_lock);
+ if (close(lock_fd))
+ fatal("Error closing lock file \"%s\": %m",opt_lock);
+ lock_fd=-1;
+}
+
+static void lock_close_atexit(void)
+{
+ /* Prevent some crashes of malloc(3) etc. */
+ verror_quiet=1;
+ lock_close();
+}