aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2014-06-10 03:55:35 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2014-06-10 03:55:35 +0000
commitc78c4cbc71476468ccaaa64ee9d4b280b7bcd612 (patch)
treec359831fd3d1cdb258e9630a5ca5e73032b2aa65
parentb055e9771b979f98b4b3237ce8d98f75c56b988c (diff)
made mbox locking NFS-safe (#202).
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@3407 ee746299-78ed-0310-b773-934348b2243d
-rw-r--r--ChangeLog6
-rw-r--r--configure.ac4
-rw-r--r--libsylph/mbox.c45
-rw-r--r--src/inc.c12
4 files changed, 47 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 1931f0b0..ada13eec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-06-10
+
+ * libsylph/mbox.c
+ src/inc.c
+ configure.ac: made mbox locking NFS-safe (#202).
+
2014-06-05
* libsylph/filter.c: filter_match_cond(): fixed crash on 32-bit OS
diff --git a/configure.ac b/configure.ac
index 76bea0bb..55e65d41 100644
--- a/configure.ac
+++ b/configure.ac
@@ -455,6 +455,10 @@ if test $ac_cv_dirent_d_type = yes; then
Define if `struct dirent' has `d_type' member.)
fi
+dnl Checks for liblockfile
+AC_CHECK_HEADERS(lockfile.h)
+AC_CHECK_LIB(lockfile, lockfile_create)
+
dnl Checks for header files.
AC_HEADER_DIRENT
diff --git a/libsylph/mbox.c b/libsylph/mbox.c
index d00b66de..4c0b2da7 100644
--- a/libsylph/mbox.c
+++ b/libsylph/mbox.c
@@ -33,6 +33,10 @@
#include <ctype.h>
#include <time.h>
+#ifdef HAVE_LOCKFILE_H
+# include <lockfile.h>
+#endif
+
#include "mbox.h"
#include "procmsg.h"
#include "procheader.h"
@@ -332,6 +336,17 @@ gint lock_mbox(const gchar *base, LockType type)
gint retval = 0;
if (type == LOCK_FILE) {
+#if HAVE_LIBLOCKFILE
+ gchar *lockfile;
+
+ lockfile = g_strconcat(base, ".lock", NULL);
+ if (lockfile_create(lockfile, 0, L_PID) != L_SUCCESS) {
+ FILE_OP_ERROR(lockfile, "lockfile_create");
+ g_free(lockfile);
+ return -1;
+ }
+ g_free(lockfile);
+#else
gchar *lockfile, *locklink;
gint retry = 0;
FILE *lockfp;
@@ -365,28 +380,23 @@ gint lock_mbox(const gchar *base, LockType type)
}
g_unlink(lockfile);
g_free(lockfile);
+#endif /* HAVE_LIBLOCKFILE */
} else if (type == LOCK_FLOCK) {
gint lockfd;
-#if HAVE_FLOCK
- if ((lockfd = open(base, O_RDONLY)) < 0) {
-#else
if ((lockfd = open(base, O_RDWR)) < 0) {
-#endif
FILE_OP_ERROR(base, "open");
return -1;
}
-#if HAVE_FLOCK
- if (flock(lockfd, LOCK_EX|LOCK_NB) < 0) {
- perror("flock");
-#else
#if HAVE_LOCKF
if (lockf(lockfd, F_TLOCK, 0) < 0) {
perror("lockf");
+#elif HAVE_FLOCK
+ if (flock(lockfd, LOCK_EX|LOCK_NB) < 0) {
+ perror("flock");
#else
{
-#endif
-#endif /* HAVE_FLOCK */
+#endif /* HAVE_LOCKF */
g_warning(_("can't lock %s\n"), base);
if (close(lockfd) < 0)
perror("close");
@@ -410,8 +420,13 @@ gint unlock_mbox(const gchar *base, gint fd, LockType type)
gchar *lockfile;
lockfile = g_strconcat(base, ".lock", NULL);
+#if HAVE_LIBLOCKFILE
+ if (lockfile_remove(lockfile) != L_SUCCESS) {
+ FILE_OP_ERROR(lockfile, "lockfile_remove");
+#else
if (g_unlink(lockfile) < 0) {
FILE_OP_ERROR(lockfile, "unlink");
+#endif /* HAVE_LIBLOCKFILE */
g_free(lockfile);
return -1;
}
@@ -419,17 +434,15 @@ gint unlock_mbox(const gchar *base, gint fd, LockType type)
return 0;
} else if (type == LOCK_FLOCK) {
-#if HAVE_FLOCK
- if (flock(fd, LOCK_UN) < 0) {
- perror("flock");
-#else
#if HAVE_LOCKF
if (lockf(fd, F_ULOCK, 0) < 0) {
perror("lockf");
+#elif HAVE_FLOCK
+ if (flock(fd, LOCK_UN) < 0) {
+ perror("flock");
#else
{
-#endif
-#endif /* HAVE_FLOCK */
+#endif /* HAVE_LOCKF */
g_warning(_("can't unlock %s\n"), base);
if (close(fd) < 0)
perror("close");
diff --git a/src/inc.c b/src/inc.c
index 7ae0426b..011a9fa9 100644
--- a/src/inc.c
+++ b/src/inc.c
@@ -1819,6 +1819,7 @@ static gint get_spool(FolderItem *dest, const gchar *mbox)
{
gint msgs, size;
gint lockfd;
+ LockType locktype = LOCK_FLOCK;
gchar tmp_mbox[MAXPATHLEN + 1];
GHashTable *folder_table = NULL;
@@ -1831,14 +1832,17 @@ static gint get_spool(FolderItem *dest, const gchar *mbox)
} else if (size < 0)
return -1;
- if ((lockfd = lock_mbox(mbox, LOCK_FLOCK)) < 0)
- return -1;
+ if ((lockfd = lock_mbox(mbox, locktype)) < 0) {
+ locktype = LOCK_FILE;
+ if ((lockfd = lock_mbox(mbox, locktype)) < 0)
+ return -1;
+ }
g_snprintf(tmp_mbox, sizeof(tmp_mbox), "%s%ctmpmbox.%p",
get_tmp_dir(), G_DIR_SEPARATOR, mbox);
if (copy_mbox(mbox, tmp_mbox) < 0) {
- unlock_mbox(mbox, lockfd, LOCK_FLOCK);
+ unlock_mbox(mbox, lockfd, locktype);
return -1;
}
@@ -1854,7 +1858,7 @@ static gint get_spool(FolderItem *dest, const gchar *mbox)
g_unlink(tmp_mbox);
if (msgs >= 0) empty_mbox(mbox);
- unlock_mbox(mbox, lockfd, LOCK_FLOCK);
+ unlock_mbox(mbox, lockfd, locktype);
if (!prefs_common.scan_all_after_inc) {
inc_update_folder_foreach(folder_table);