From: Timo Sirainen Date: Wed, 21 Jun 2017 22:47:51 +0000 (+0300) Subject: lib: Add file_lock_set_unlink_on_free() X-Git-Tag: 2.3.0.rc1~1365 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=68332e3a49dea15013aa8f4daa16b5e07eb3d543;p=thirdparty%2Fdovecot%2Fcore.git lib: Add file_lock_set_unlink_on_free() --- diff --git a/src/lib/file-lock.c b/src/lib/file-lock.c index 2b686dcab6..3478fa829e 100644 --- a/src/lib/file-lock.c +++ b/src/lib/file-lock.c @@ -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); diff --git a/src/lib/file-lock.h b/src/lib/file-lock.h index 2d36222953..377abdbf8c 100644 --- a/src/lib/file-lock.h +++ b/src/lib/file-lock.h @@ -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);