commit 5c606d419912680015c8c4ab1d78e895e32233fe
parent f5b8cdb85f2a18f55fe19fd195c009d0f0c73860
Author: Oliver Lowe <o@olowe.co>
Date: Sat, 30 Aug 2025 16:26:21 +1000
Just use flock(2)
This project is very POSIX-y already so the workarounds don't actually
get us anywhere
Diffstat:
6 files changed, 30 insertions(+), 254 deletions(-)
diff --git a/configure.ac b/configure.ac
@@ -212,7 +212,7 @@ AC_CHECK_SIZEOF(unsigned long, 4)
dnl Checks for library functions.
AC_FUNC_ALLOCA
-AC_CHECK_FUNCS(fchmod flock lockf strcasestr)
+AC_CHECK_FUNCS(strcasestr)
dnl *****************
dnl ** common code **
diff --git a/src/common/file-utils.c b/src/common/file-utils.c
@@ -664,11 +664,7 @@ gint copy_dir(const gchar *src, const gchar *dst)
gint change_file_mode_rw(FILE *fp, const gchar *file)
{
-#if HAVE_FCHMOD
return fchmod(fileno(fp), S_IRUSR|S_IWUSR);
-#else
- return g_chmod(file, S_IRUSR|S_IWUSR);
-#endif
}
FILE *my_tmpfile(void)
diff --git a/src/inc.c b/src/inc.c
@@ -23,6 +23,7 @@
#include "defs.h"
+#include <fcntl.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
@@ -663,7 +664,6 @@ static gint inc_start(IncProgressDialog *inc_dialog)
for (; inc_dialog->queue_list != NULL && !cancelled; inc_dialog->cur_row++) {
session = inc_dialog->queue_list->data;
pop3_session = POP3_SESSION(session->session);
- GSList *filtered, *unfiltered;
if (pop3_session->pass == NULL) {
SET_PIXMAP_AND_TEXT(okpix, _("Cancelled"));
@@ -754,9 +754,6 @@ static gint inc_start(IncProgressDialog *inc_dialog)
/* process messages */
folder_item_update_freeze();
- if (unfiltered != NULL)
- folder_item_move_msgs(inbox, unfiltered);
-
for(msglist_element = msglist; msglist_element != NULL;
msglist_element = msglist_element->next) {
procmsg_msginfo_free((MsgInfo**)&(msglist_element->data));
@@ -764,8 +761,6 @@ static gint inc_start(IncProgressDialog *inc_dialog)
folder_item_update_thaw();
g_slist_free(msglist);
- g_slist_free(filtered);
- g_slist_free(unfiltered);
statusbar_pop_all();
@@ -1379,7 +1374,6 @@ static gint inc_spool_account(PrefsAccount *account)
static gint get_spool(FolderItem *dest, const gchar *mbox, PrefsAccount *account)
{
gint msgs, size;
- gint lockfd;
gchar tmp_mbox[MAXPATHLEN + 1];
cm_return_val_if_fail(dest != NULL, -1);
@@ -1387,30 +1381,34 @@ static gint get_spool(FolderItem *dest, const gchar *mbox, PrefsAccount *account
cm_return_val_if_fail(account != NULL, -1);
if (!is_file_exist(mbox) || (size = get_file_size(mbox)) == 0) {
- debug_print("%s: no messages in local mailbox.\n", mbox);
+ debug_print("%s: no messages\n", mbox);
return 0;
} else if (size < 0)
return -1;
- if ((lockfd = lock_mbox(mbox, LOCK_FLOCK)) < 0)
- return -1;
-
- g_snprintf(tmp_mbox, sizeof(tmp_mbox), "%s%ctmpmbox.%p",
- get_tmp_dir(), G_DIR_SEPARATOR, mbox);
+ g_snprintf(tmp_mbox, sizeof(tmp_mbox), "%s/tmpmbox.%p", get_tmp_dir(), mbox);
- if (copy_mbox(lockfd, tmp_mbox) < 0) {
- unlock_mbox(mbox, lockfd, LOCK_FLOCK);
+ int spool = open(mbox, O_RDONLY);
+ if (flock(spool, LOCK_EX|LOCK_NB) < 0) {
+ perror("lock mbox");
return -1;
}
-
- debug_print("Getting new messages from %s into %s...\n",
- mbox, dest->path);
+ debug_print("Getting new messages from %s into %s...\n", mbox, dest->path);
+ if (copy_mbox(spool, tmp_mbox) < 0) {
+ flock(spool, LOCK_UN);
+ close(spool);
+ return -1;
+ }
+ close(spool);
msgs = proc_mbox(dest, tmp_mbox, FALSE, account);
-
unlink(tmp_mbox);
- if (msgs >= 0) empty_mbox(mbox);
- unlock_mbox(mbox, lockfd, LOCK_FLOCK);
+ if (msgs >= 0) {
+ if (truncate(mbox, 0) < 0)
+ perror("truncate mbox");
+ }
+
+ flock(spool, LOCK_UN);
return msgs;
}
diff --git a/src/main.c b/src/main.c
@@ -27,24 +27,19 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
-#include <stdbool.h>
#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <time.h>
+#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
-#ifdef G_OS_UNIX
-# include <signal.h>
-# include <errno.h>
-# include <fcntl.h>
-#endif
-
-#if HAVE_FLOCK
-#include <sys/file.h>
-#endif
+#include <time.h>
+#include <unistd.h>
#ifdef HAVE_VALGRIND
#include <valgrind.h>
@@ -1314,7 +1309,6 @@ static gint prohibit_duplicate_launch(int *argc, char ***argv)
{
gint sock;
GList *curr;
-#ifdef G_OS_UNIX
gchar *path;
path = claws_get_socket_name();
@@ -1323,7 +1317,6 @@ static gint prohibit_duplicate_launch(int *argc, char ***argv)
if (sock < 0) {
gint ret;
-#if HAVE_FLOCK
gchar *socket_lock;
gint lock_fd;
/* If connect failed, no other process is running.
@@ -1349,38 +1342,16 @@ static gint prohibit_duplicate_launch(int *argc, char ***argv)
g_free(socket_lock);
return -1;
}
-#endif
unlink(path);
debug_print("Opening socket %s\n", path);
ret = fd_open_unix(path);
-#if HAVE_FLOCK
flock(lock_fd, LOCK_UN);
close(lock_fd);
unlink(socket_lock);
g_free(socket_lock);
-#endif
return ret;
}
-#else
- HANDLE hmutex;
-
- hmutex = CreateMutexA(NULL, FALSE, "ClawsMail");
- if (!hmutex) {
- debug_print("cannot create Mutex\n");
- return -1;
- }
- if (GetLastError() != ERROR_ALREADY_EXISTS) {
- sock = fd_open_inet(50216);
- if (sock < 0)
- return 0;
- return sock;
- }
-
- sock = fd_connect_inet(50216);
- if (sock < 0)
- return -1;
-#endif
/* remote command mode */
debug_print("another Claws Mail instance is already running.\n");
diff --git a/src/mbox.c b/src/mbox.c
@@ -258,171 +258,6 @@ gint proc_mbox(FolderItem *dest, const gchar *mbox, gboolean apply_filter,
return msgs;
}
-gint lock_mbox(const gchar *base, LockType type)
-{
-#ifdef G_OS_UNIX
- gint retval = 0;
-
- if (type == LOCK_FILE) {
- gchar *lockfile, *locklink;
- gint retry = 0;
- FILE *lockfp;
-
- lockfile = g_strdup_printf("%s.%d", base, getpid());
- if ((lockfp = g_fopen(lockfile, "wb")) == NULL) {
- FILE_OP_ERROR(lockfile, "g_fopen");
- g_warning("can't create lock file '%s', use 'flock' instead of 'file' if possible", lockfile);
- g_free(lockfile);
- return -1;
- }
-
- if (fprintf(lockfp, "%d\n", getpid()) < 0) {
- FILE_OP_ERROR(lockfile, "fprintf");
- g_free(lockfile);
- fclose(lockfp);
- return -1;
- }
-
- if (safe_fclose(lockfp) == EOF) {
- FILE_OP_ERROR(lockfile, "fclose");
- g_free(lockfile);
- return -1;
- }
-
- locklink = g_strconcat(base, ".lock", NULL);
- while (link(lockfile, locklink) < 0) {
- FILE_OP_ERROR(lockfile, "link");
- if (retry >= 5) {
- g_warning("can't create '%s'", lockfile);
- unlink(lockfile);
- g_free(locklink);
- g_free(lockfile);
- return -1;
- }
- if (retry == 0)
- g_warning("mailbox is owned by another process, waiting");
- retry++;
- sleep(5);
- }
- unlink(lockfile);
- g_free(locklink);
- g_free(lockfile);
- } else if (type == LOCK_FLOCK) {
- gint lockfd;
- gboolean fcntled = FALSE;
-#if HAVE_FCNTL_H && !defined(G_OS_WIN32)
- struct flock fl;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
-#endif
-
-#if HAVE_FLOCK
- if ((lockfd = g_open(base, O_RDWR, 0)) < 0) {
-#else
- if ((lockfd = g_open(base, O_RDWR, 0)) < 0) {
-#endif
- FILE_OP_ERROR(base, "open");
- return -1;
- }
-
-#if HAVE_FCNTL_H && !defined(G_OS_WIN32)
- if (fcntl(lockfd, F_SETLK, &fl) == -1) {
- g_warning("can't fnctl %s (%s)", base, g_strerror(errno));
- close(lockfd);
- return -1;
- } else {
- fcntled = TRUE;
- }
-#endif
-
-#if HAVE_FLOCK
- if (flock(lockfd, LOCK_EX|LOCK_NB) < 0 && !fcntled) {
- perror("flock");
-#else
-#if HAVE_LOCKF
- if (lockf(lockfd, F_TLOCK, 0) < 0 && !fcntled) {
- perror("lockf");
-#else
- {
-#endif
-#endif /* HAVE_FLOCK */
- g_warning("can't lock %s", base);
- if (close(lockfd) < 0)
- perror("close");
- return -1;
- }
- retval = lockfd;
- } else {
- g_warning("invalid lock type");
- return -1;
- }
-
- return retval;
-#else
- return -1;
-#endif /* G_OS_UNIX */
-}
-
-gint unlock_mbox(const gchar *base, gint fd, LockType type)
-{
- if (type == LOCK_FILE) {
- gchar *lockfile;
-
- lockfile = g_strconcat(base, ".lock", NULL);
- if (unlink(lockfile) < 0) {
- FILE_OP_ERROR(lockfile, "unlink");
- g_free(lockfile);
- return -1;
- }
- g_free(lockfile);
-
- return 0;
- } else if (type == LOCK_FLOCK) {
-#if HAVE_FCNTL_H && !defined(G_OS_WIN32)
- gboolean fcntled = FALSE;
- struct flock fl;
- fl.l_type = F_UNLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
-
- if (fcntl(fd, F_SETLK, &fl) == -1) {
- g_warning("can't fnctl %s", base);
- } else {
- fcntled = TRUE;
- }
-#endif
-#if HAVE_FLOCK
- if (flock(fd, LOCK_UN) < 0 && !fcntled) {
- perror("flock");
-#else
-#if HAVE_LOCKF
- if (lockf(fd, F_ULOCK, 0) < 0 && !fcntled) {
- perror("lockf");
-#else
- {
-#endif
-#endif /* HAVE_FLOCK */
- g_warning("can't unlock %s", base);
- if (close(fd) < 0)
- perror("close");
- return -1;
- }
-
- if (close(fd) < 0) {
- perror("close");
- return -1;
- }
-
- return 0;
- }
-
- g_warning("invalid lock type");
- return -1;
-}
-
gint copy_mbox(gint srcfd, const gchar *dest)
{
FILE *dest_fp;
@@ -473,18 +308,6 @@ gint copy_mbox(gint srcfd, const gchar *dest)
return 0;
}
-void empty_mbox(const gchar *mbox)
-{
- FILE *fp;
-
- if ((fp = g_fopen(mbox, "wb")) == NULL) {
- FILE_OP_ERROR(mbox, "g_fopen");
- g_warning("can't truncate mailbox to zero");
- return;
- }
- safe_fclose(fp);
-}
-
gint export_list_to_mbox(GSList *mlist, const gchar *mbox)
/* return values: -2 skipped, -1 error, 0 OK */
{
diff --git a/src/mbox.h b/src/mbox.h
@@ -14,7 +14,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ *
*/
#ifndef __MBOX_H__
@@ -24,28 +24,16 @@
#include "folder.h"
-typedef enum {
- LOCK_FILE,
- LOCK_FLOCK
-} LockType;
-
-
gint proc_mbox (FolderItem *dest,
const gchar *mbox,
gboolean apply_filter,
PrefsAccount *account);
-gint lock_mbox (const gchar *base,
- LockType type);
-gint unlock_mbox (const gchar *base,
- gint fd,
- LockType type);
gint copy_mbox (gint srcfd,
const gchar *dest);
-void empty_mbox (const gchar *mbox);
gint export_to_mbox (FolderItem *src,
const gchar *mbox);
-gint export_list_to_mbox(GSList *mlist,
+gint export_list_to_mbox(GSList *mlist,
const gchar *mbox);
#endif /* __MBOX_H__ */