file-lock.c revision 0dc7891233a973829f00371b27810f849b987c66
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2002-2014 Dovecot authors, see the included COPYING file */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "file-lock.h"
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen#ifdef HAVE_FLOCK
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# include <sys/file.h>
5666a3d6a7ea89362b8d9e8b39b15424cd9d6388Timo Sirainen#endif
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstruct file_lock {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int fd;
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen char *path;
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen int lock_type;
3ed2d0f6b5e67e2663d44489d9da3176823789a8Timo Sirainen enum file_lock_method lock_method;
65f8fb656051f1059f7b5a2da9c5555adcc30439Timo Sirainen};
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenbool file_lock_method_parse(const char *name, enum file_lock_method *method_r)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (strcasecmp(name, "fcntl") == 0)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen *method_r = FILE_LOCK_METHOD_FCNTL;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen else if (strcasecmp(name, "flock") == 0)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen *method_r = FILE_LOCK_METHOD_FLOCK;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen else if (strcasecmp(name, "dotlock") == 0)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen *method_r = FILE_LOCK_METHOD_DOTLOCK;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen else
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return FALSE;
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen return TRUE;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen}
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst char *file_lock_method_to_str(enum file_lock_method method)
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen{
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen switch (method) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen case FILE_LOCK_METHOD_FCNTL:
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return "fcntl";
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen case FILE_LOCK_METHOD_FLOCK:
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return "flock";
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen case FILE_LOCK_METHOD_DOTLOCK:
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return "dotlock";
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen }
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen i_unreached();
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen}
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen
3e564425db51f3921ce4de11859777135fdedd15Timo Sirainenint file_try_lock(int fd, const char *path, int lock_type,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen enum file_lock_method lock_method,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct file_lock **lock_r)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen return file_wait_lock(fd, path, lock_type, lock_method, 0, lock_r);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen}
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenint file_try_lock_error(int fd, const char *path, int lock_type,
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen enum file_lock_method lock_method,
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen struct file_lock **lock_r, const char **error_r)
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen{
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen return file_wait_lock_error(fd, path, lock_type, lock_method, 0,
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen lock_r, error_r);
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen}
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainenstatic int file_lock_do(int fd, const char *path, int lock_type,
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen enum file_lock_method lock_method,
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen unsigned int timeout_secs, const char **error_r)
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen{
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen const char *lock_type_str;
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen int ret;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen i_assert(fd != -1);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen if (timeout_secs != 0)
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen alarm(timeout_secs);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen lock_type_str = lock_type == F_UNLCK ? "unlock" :
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen (lock_type == F_RDLCK ? "read-lock" : "write-lock");
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen switch (lock_method) {
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen case FILE_LOCK_METHOD_FCNTL: {
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen#ifndef HAVE_FCNTL
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen *error_r = t_strdup_printf(
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen "Can't lock file %s: fcntl() locks not supported", path);
57a8c6a95e4bce3eeaba36985adb81c07dd683ffTimo Sirainen return -1;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen#else
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct flock fl;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fl.l_type = lock_type;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen fl.l_whence = SEEK_SET;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen fl.l_start = 0;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen fl.l_len = 0;
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen ret = fcntl(fd, timeout_secs ? F_SETLKW : F_SETLK, &fl);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen if (timeout_secs != 0) alarm(0);
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen if (ret == 0)
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen break;
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen if (timeout_secs == 0 &&
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen (errno == EACCES || errno == EAGAIN)) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* locked by another process */
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen *error_r = t_strdup_printf(
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen "fcntl(%s, %s, F_SETLK) locking failed: %m "
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen "(File is already locked)", path, lock_type_str);
f1743785713e7632459d623d5df2108f4b93accbTimo Sirainen return 0;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen }
70ead6466f9baa8294e71fc2fba0a4f54f488b5eTimo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (errno == EINTR) {
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen /* most likely alarm hit, meaning we timeouted.
8d630c15a8ed6f85553467c3a231a273defca5f6Timo Sirainen even if not, we probably want to be killed
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen so stop blocking. */
ee116df08d0fdab703483e18fe8076b2ef9fd9d7Timo Sirainen errno = EAGAIN;
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen *error_r = t_strdup_printf(
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen "fcntl(%s, %s, F_SETLKW) locking failed: "
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen "Timed out after %u seconds",
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen path, lock_type_str, timeout_secs);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return 0;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *error_r = t_strdup_printf("fcntl(%s, %s, %s) locking failed: %m",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen path, lock_type_str, timeout_secs == 0 ? "F_SETLK" : "F_SETLKW");
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen return -1;
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen#endif
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen }
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen case FILE_LOCK_METHOD_FLOCK: {
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen#ifndef HAVE_FLOCK
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen *error_r = t_strdup_printf(
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen "Can't lock file %s: flock() not supported", path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen#else
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen int operation = timeout_secs != 0 ? 0 : LOCK_NB;
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen switch (lock_type) {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen case F_RDLCK:
e03d986a74128f5ba30fcfda9f6e36578f5d8decTimo Sirainen operation |= LOCK_SH;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen case F_WRLCK:
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen operation |= LOCK_EX;
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen break;
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen case F_UNLCK:
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen operation |= LOCK_UN;
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen break;
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen }
d3280fe317a4598c0868cc440e7a1191c06d0db3Timo Sirainen
d3280fe317a4598c0868cc440e7a1191c06d0db3Timo Sirainen ret = flock(fd, operation);
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen if (timeout_secs != 0) alarm(0);
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen if (ret == 0)
6469cf211a57433335641725dc236ebb2b9fdd3bTimo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen if (timeout_secs == 0 && errno == EWOULDBLOCK) {
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen /* locked by another process */
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen *error_r = t_strdup_printf(
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen "flock(%s, %s) failed: %m "
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen "(File is already locked)", path, lock_type_str);
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen return 0;
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen }
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen if (errno == EINTR) {
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen errno = EAGAIN;
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen *error_r = t_strdup_printf("flock(%s, %s) failed: "
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen "Timed out after %u seconds",
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen path, lock_type_str, timeout_secs);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen return 0;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen }
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen *error_r = t_strdup_printf("flock(%s, %s) failed: %m",
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen path, lock_type_str);
2584e86cc2d8c31ba30a4109cf4ba09d1e37e28aTimo Sirainen return -1;
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen#endif
4b41116563110d00330896a568eff1078c382827Timo Sirainen }
4b41116563110d00330896a568eff1078c382827Timo Sirainen case FILE_LOCK_METHOD_DOTLOCK:
4b41116563110d00330896a568eff1078c382827Timo Sirainen /* we shouldn't get here */
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen i_unreached();
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen }
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenint file_wait_lock(int fd, const char *path, int lock_type,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen enum file_lock_method lock_method,
b2c1349cf07410aefab0f5b17153af9e5cfcf48fTimo Sirainen unsigned int timeout_secs,
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen struct file_lock **lock_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
dbe64f3893616a4005c8946be75d2dc8f6823d72Timo Sirainen const char *error;
8a13b020f90e080570658b18c042e7e352c8b14fTimo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ret = file_wait_lock_error(fd, path, lock_type, lock_method,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen timeout_secs, lock_r, &error);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (ret < 0)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_error("%s", error);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainenint file_wait_lock_error(int fd, const char *path, int lock_type,
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen enum file_lock_method lock_method,
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen unsigned int timeout_secs,
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen struct file_lock **lock_r, const char **error_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
f3bb2fbe87425dc89a839908985af496f7f65702Timo Sirainen struct file_lock *lock;
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen int ret;
a3ee5ce6ecc8e228ee69300fdd562d7ac8be89a7Timo Sirainen
bd1b2615928a1e8be190cb0405754f0aec8cac2fTimo Sirainen ret = file_lock_do(fd, path, lock_type, lock_method, timeout_secs, error_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret <= 0)
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen return ret;
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen lock = i_new(struct file_lock, 1);
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen lock->fd = fd;
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen lock->path = i_strdup(path);
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen lock->lock_type = lock_type;
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen lock->lock_method = lock_method;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *lock_r = lock;
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen return 1;
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen}
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainenint file_lock_try_update(struct file_lock *lock, int lock_type)
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen{
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen const char *error;
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen return file_lock_do(lock->fd, lock->path, lock_type,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen lock->lock_method, 0, &error);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenvoid file_unlock(struct file_lock **_lock)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct file_lock *lock = *_lock;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const char *error;
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen *_lock = NULL;
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen if (file_lock_do(lock->fd, lock->path, F_UNLCK,
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen lock->lock_method, 0, &error) == 0) {
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen /* this shouldn't happen */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_error("file_unlock(%s) failed: %m", lock->path);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen }
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen file_lock_free(&lock);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid file_lock_free(struct file_lock **_lock)
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct file_lock *lock = *_lock;
d938e9e4ec4c0f326dffd5ebe42c1ad893ce7e52Timo Sirainen
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen *_lock = NULL;
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen i_free(lock->path);
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen i_free(lock);
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen}
ca98d6a1bbe73499da758a36bfab2963375c8d06Timo Sirainen