]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Add file_lock_from_dotlock()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 6 Feb 2018 15:35:18 +0000 (17:35 +0200)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Fri, 9 Feb 2018 14:09:22 +0000 (16:09 +0200)
The dotlock creation requires various settings, so the file-lock.h API can't
easily be used to create it. But once created, it's simpler to keep all lock
types in the same struct file_lock, which can be unlocked/freed once
finished.

src/lib/file-lock.c
src/lib/file-lock.h

index 0b53f074bd11d82232dcbc5b632b201b5495a4ae..7a8cc4ec161065deea6d0467212db8fd02512c03 100644 (file)
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "istream.h"
 #include "file-lock.h"
+#include "file-dotlock.h"
 #include "time-util.h"
 
 #include <time.h>
@@ -14,6 +15,7 @@
 struct file_lock {
        int fd;
        char *path;
+       struct dotlock *dotlock;
 
        struct timeval locked_time;
        int lock_type;
@@ -352,6 +354,23 @@ void file_lock_set_close_on_free(struct file_lock *lock, bool set)
        lock->close_on_free = set;
 }
 
+struct file_lock *file_lock_from_dotlock(struct dotlock **dotlock)
+{
+       struct file_lock *lock;
+
+       lock = i_new(struct file_lock, 1);
+       lock->fd = -1;
+       lock->path = i_strdup(file_dotlock_get_lock_path(*dotlock));
+       lock->lock_type = F_WRLCK;
+       lock->lock_method = FILE_LOCK_METHOD_DOTLOCK;
+       if (gettimeofday(&lock->locked_time, NULL) < 0)
+               i_fatal("gettimeofday() failed: %m");
+       lock->dotlock = *dotlock;
+
+       *dotlock = NULL;
+       return lock;
+}
+
 static void file_unlock_real(struct file_lock *lock)
 {
        const char *error;
@@ -374,7 +393,8 @@ void file_unlock(struct file_lock **_lock)
           could be deleting the new lock. */
        i_assert(!lock->unlink_on_free);
 
-       file_unlock_real(lock);
+       if (lock->dotlock == NULL)
+               file_unlock_real(lock);
        file_lock_free(&lock);
 }
 
@@ -419,6 +439,8 @@ void file_lock_free(struct file_lock **_lock)
 
        *_lock = NULL;
 
+       if (lock->dotlock != NULL)
+               file_dotlock_delete(&lock->dotlock);
        if (lock->unlink_on_free)
                file_try_unlink_locked(lock);
        if (lock->close_on_free)
index e4d6eb19fe6ff13a2aeec80d407b81cfd17ce277..d32d5f8029470b87bba14f95bf4fa86f4102aa99 100644 (file)
@@ -7,6 +7,7 @@
 #define DEFAULT_LOCK_TIMEOUT 120
 
 struct file_lock;
+struct dotlock;
 
 enum file_lock_method {
        FILE_LOCK_METHOD_FCNTL,
@@ -53,6 +54,10 @@ void file_lock_set_unlink_on_free(struct file_lock *lock, bool set);
    be useful for files that are only created to exist as lock files. */
 void file_lock_set_close_on_free(struct file_lock *lock, bool set);
 
+/* Convert dotlock into file_lock, which can be deleted with either
+   file_unlock() or file_lock_free(). */
+struct file_lock *file_lock_from_dotlock(struct dotlock **dotlock);
+
 /* Unlock and free the lock. */
 void file_unlock(struct file_lock **lock);
 /* Free the lock without unlocking it (because you're closing the fd anyway). */