summaryrefslogtreecommitdiff
path: root/lib-src
diff options
context:
space:
mode:
Diffstat (limited to 'lib-src')
-rw-r--r--lib-src/movemail.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/lib-src/movemail.c b/lib-src/movemail.c
index 80f6afd3616..79ea6dcabab 100644
--- a/lib-src/movemail.c
+++ b/lib-src/movemail.c
@@ -295,6 +295,9 @@ main (argc, argv)
if (fork () == 0)
{
+ int lockcount = 0;
+ int status;
+
setuid (getuid ());
#ifndef MAIL_USE_MMDF
@@ -320,22 +323,53 @@ main (argc, argv)
outdesc = open (outname, O_WRONLY | O_CREAT | O_EXCL, 0666);
if (outdesc < 0)
pfatal_with_name (outname);
+
+ /* This label exists so we can retry locking
+ after a delay, if it got EAGAIN or EBUSY. */
+ retry_lock:
+
+ /* Try to lock it. */
#ifdef MAIL_USE_SYSTEM_LOCK
#ifdef MAIL_USE_LOCKF
- if (lockf (indesc, F_LOCK, 0) < 0) pfatal_with_name (inname);
+ status = lockf (indesc, F_LOCK, 0);
#else /* not MAIL_USE_LOCKF */
#ifdef XENIX
- if (locking (indesc, LK_RLCK, 0L) < 0) pfatal_with_name (inname);
+ status = locking (indesc, LK_RLCK, 0L);
#else
#ifdef WINDOWSNT
- if (locking (indesc, LK_RLCK, -1L) < 0) pfatal_with_name (inname);
+ status = locking (indesc, LK_RLCK, -1L);
#else
- if (flock (indesc, LOCK_EX) < 0) pfatal_with_name (inname);
+ status = flock (indesc, LOCK_EX);
#endif
#endif
#endif /* not MAIL_USE_LOCKF */
#endif /* MAIL_USE_SYSTEM_LOCK */
+ /* If it fails, retry up to 5 times
+ for certain failure codes. */
+ if (status < 0)
+ {
+ if (++lockcount <= 5)
+ {
+#ifdef EAGAIN
+ if (errno == EAGAIN)
+ {
+ sleep (1);
+ goto retry_lock;
+ }
+#endif
+#ifdef EBUSY
+ if (errno == EBUSY)
+ {
+ sleep (1);
+ goto retry_lock;
+ }
+#endif
+ }
+
+ pfatal_with_name (inname);
+ }
+
{
char buf[1024];