summaryrefslogtreecommitdiffstats
path: root/mbox.c
diff options
context:
space:
mode:
authorKevin McCarthy <kevin@8t8.us>2018-06-14 16:17:56 +0800
committerKevin McCarthy <kevin@8t8.us>2018-06-18 13:05:15 +0800
commit120f63a9bea469e9980cf0270a1bb54841051015 (patch)
tree6f79cf91c8b53750d7daee1708bcfc929539e077 /mbox.c
parent7ec17b81882bcc58fd7f73bef8ef4b74439eb3f8 (diff)
Convert context and buffy to use nanosecond timestamps.
The inotify interface has an unfortunate side effect of making Mutt react too quickly to new mail. Sometimes, the mail is only half-delivered when the mailbox is checked. Because Mutt is using the stat mtime - seconds resolution - this means it won't realize there are more messages delivered during the same second. Nanosecond resolution fields were standardized in POSIX.1-2008, so check for and use those if they are available.
Diffstat (limited to 'mbox.c')
-rw-r--r--mbox.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/mbox.c b/mbox.c
index 34668832..171689f0 100644
--- a/mbox.c
+++ b/mbox.c
@@ -90,6 +90,9 @@ int mmdf_parse_mailbox (CONTEXT *ctx)
HEADER *hdr;
struct stat sb;
#ifdef NFS_ATTRIBUTE_HACK
+#ifdef HAVE_UTIMENSAT
+ struct timespec ts[2];
+#endif /* HAVE_UTIMENSAT */
struct utimbuf newtime;
#endif
progress_t progress;
@@ -100,16 +103,24 @@ int mmdf_parse_mailbox (CONTEXT *ctx)
mutt_perror (ctx->path);
return (-1);
}
- ctx->atime = sb.st_atime;
- ctx->mtime = sb.st_mtime;
+ mutt_get_stat_timespec (&ctx->atime, &sb, MUTT_STAT_ATIME);
+ mutt_get_stat_timespec (&ctx->mtime, &sb, MUTT_STAT_MTIME);
ctx->size = sb.st_size;
#ifdef NFS_ATTRIBUTE_HACK
if (sb.st_mtime > sb.st_atime)
{
- newtime.modtime = sb.st_mtime;
+#ifdef HAVE_UTIMENSAT
+ ts[0].tv_sec = 0;
+ ts[0].tv_nsec = UTIME_NOW;
+ ts[1].tv_sec = 0;
+ ts[1].tv_nsec = UTIME_OMIT;
+ utimensat (0, ctx->path, ts, 0);
+#else
newtime.actime = time (NULL);
+ newtime.modtime = sb.st_mtime;
utime (ctx->path, &newtime);
+#endif /* HAVE_UTIMENSAT */
}
#endif
@@ -238,6 +249,9 @@ int mbox_parse_mailbox (CONTEXT *ctx)
int count = 0, lines = 0;
LOFF_T loc;
#ifdef NFS_ATTRIBUTE_HACK
+#ifdef HAVE_UTIMENSAT
+ struct timespec ts[2];
+#endif /* HAVE_UTIMENSAT */
struct utimbuf newtime;
#endif
progress_t progress;
@@ -251,15 +265,23 @@ int mbox_parse_mailbox (CONTEXT *ctx)
}
ctx->size = sb.st_size;
- ctx->mtime = sb.st_mtime;
- ctx->atime = sb.st_atime;
+ mutt_get_stat_timespec (&ctx->mtime, &sb, MUTT_STAT_MTIME);
+ mutt_get_stat_timespec (&ctx->atime, &sb, MUTT_STAT_ATIME);
#ifdef NFS_ATTRIBUTE_HACK
if (sb.st_mtime > sb.st_atime)
{
- newtime.modtime = sb.st_mtime;
+#ifdef HAVE_UTIMENSAT
+ ts[0].tv_sec = 0;
+ ts[0].tv_nsec = UTIME_NOW;
+ ts[1].tv_sec = 0;
+ ts[1].tv_nsec = UTIME_OMIT;
+ utimensat (0, ctx->path, ts, 0);
+#else
newtime.actime = time (NULL);
+ newtime.modtime = sb.st_mtime;
utime (ctx->path, &newtime);
+#endif /* HAVE_UTIMENSAT */
}
#endif
@@ -666,13 +688,14 @@ static int mbox_check_mailbox (CONTEXT *ctx, int *index_hint)
if (stat (ctx->path, &st) == 0)
{
- if (st.st_mtime == ctx->mtime && st.st_size == ctx->size)
+ if ((mutt_stat_timespec_compare (&st, MUTT_STAT_MTIME, &ctx->mtime) == 0) &&
+ st.st_size == ctx->size)
return (0);
if (st.st_size == ctx->size)
{
/* the file was touched, but it is still the same length, so just exit */
- ctx->mtime = st.st_mtime;
+ mutt_get_stat_timespec (&ctx->mtime, &st, MUTT_STAT_MTIME);
return (0);
}