]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Add file_lock_set_unlink_on_free()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 21 Jun 2017 22:47:51 +0000 (01:47 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 3 Jul 2017 12:13:24 +0000 (15:13 +0300)
src/lib/file-lock.c
src/lib/file-lock.h

index e96d06b0dd11e33102d032b554d926db7becb0b6..bef1548c09a02212eb23bd79b240cb36252cfe8e 100644 (file)
@@ -18,6 +18,7 @@ struct file_lock {
        struct timeval locked_time;
        int lock_type;
        enum file_lock_method lock_method;
+       bool unlink_on_free;
 };
 
 static struct timeval lock_wait_start;
@@ -340,6 +341,11 @@ int file_lock_try_update(struct file_lock *lock, int lock_type)
        return 1;
 }
 
+void file_lock_set_unlink_on_free(struct file_lock *lock, bool set)
+{
+       lock->unlink_on_free = set;
+}
+
 void file_unlock(struct file_lock **_lock)
 {
        struct file_lock *lock = *_lock;
@@ -347,6 +353,11 @@ void file_unlock(struct file_lock **_lock)
 
        *_lock = NULL;
 
+       /* unlocking is unnecessary when the file is unlinked. or alternatively
+          the unlink() must be done before unlocking, because otherwise it
+          could be deleting the new lock. */
+       i_assert(!lock->unlink_on_free);
+
        if (file_lock_do(lock->fd, lock->path, F_UNLCK,
                         lock->lock_method, 0, &error) == 0) {
                /* this shouldn't happen */
@@ -362,6 +373,9 @@ void file_lock_free(struct file_lock **_lock)
 
        *_lock = NULL;
 
+       if (lock->unlink_on_free)
+               i_unlink(lock->path);
+
        file_lock_log_warning_if_slow(lock);
        i_free(lock->path);
        i_free(lock);
index 2d36222953f7329e78167d911212fb42fa02cee7..377abdbf8cf8997c8131443a09b033e9f136a8b3 100644 (file)
@@ -45,6 +45,9 @@ int file_wait_lock_error(int fd, const char *path, int lock_type,
 /* Change the lock type. WARNING: This isn't an atomic operation!
    The result is the same as file_unlock() + file_try_lock(). */
 int file_lock_try_update(struct file_lock *lock, int lock_type);
+/* When the lock is freed, unlink() the file automatically. This can be useful
+   for files that are only created to exist as lock files. */
+void file_lock_set_unlink_on_free(struct file_lock *lock, bool set);
 
 /* Unlock and free the lock. */
 void file_unlock(struct file_lock **lock);