diff options
author | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2014-06-10 03:55:35 +0000 |
---|---|---|
committer | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2014-06-10 03:55:35 +0000 |
commit | c78c4cbc71476468ccaaa64ee9d4b280b7bcd612 (patch) | |
tree | c359831fd3d1cdb258e9630a5ca5e73032b2aa65 | |
parent | b055e9771b979f98b4b3237ce8d98f75c56b988c (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-- | ChangeLog | 6 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | libsylph/mbox.c | 45 | ||||
-rw-r--r-- | src/inc.c | 12 |
4 files changed, 47 insertions, 20 deletions
@@ -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"); @@ -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); |