dovecot: When checking if destination temp file exists, if stat(...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Jul 9 05:44:36 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/47d0899be687
changeset: 5906:47d0899be687
user: Timo Sirainen <tss at iki.fi>
date: Sun Jul 08 21:35:17 2007 +0300
description:
When checking if destination temp file exists, if stat() failed with anything
else than ENOENT, we got stuck infinitely.
diffstat:
1 file changed, 15 insertions(+), 7 deletions(-)
src/lib-storage/index/maildir/maildir-save.c | 22 +++++++++++++++-------
diffs (50 lines):
diff -r 81b3a22e6ce1 -r 47d0899be687 src/lib-storage/index/maildir/maildir-save.c
--- a/src/lib-storage/index/maildir/maildir-save.c Sun Jul 08 21:33:42 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-save.c Sun Jul 08 21:35:17 2007 +0300
@@ -334,7 +334,7 @@ const char *maildir_save_file_get_path(s
}
static int maildir_create_tmp(struct maildir_mailbox *mbox, const char *dir,
- mode_t mode, const char **fname_r)
+ const char **fname_r)
{
struct stat st;
unsigned int prefix_len;
@@ -355,14 +355,23 @@ static int maildir_create_tmp(struct mai
/* stat() first to see if it exists. pretty much the only
possibility of that happening is if time had moved
backwards, but even then it's highly unlikely. */
- if (stat(str_c(path), &st) < 0 && errno == ENOENT) {
+ if (stat(str_c(path), &st) == 0) {
+ /* try another file name */
+ } else if (errno != ENOENT) {
+ mail_storage_set_critical(&mbox->storage->storage,
+ "stat(%s) failed: %m", str_c(path));
+ return -1;
+ } else {
/* doesn't exist */
- mode_t old_mask = umask(0);
- fd = open(str_c(path), O_WRONLY | O_CREAT | O_EXCL,
- mode);
+ mode_t old_mask = umask(0777 & ~mbox->mail_create_mode);
+ fd = open(str_c(path),
+ O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0777);
umask(old_mask);
+
if (fd != -1 || errno != EEXIST)
break;
+ /* race condition between stat() and open().
+ highly unlikely. */
}
}
@@ -408,8 +417,7 @@ int maildir_save_init(struct mailbox_tra
ctx = t->save_ctx;
/* create a new file in tmp/ directory */
- ctx->fd = maildir_create_tmp(mbox, ctx->tmpdir, mbox->mail_create_mode,
- &fname);
+ ctx->fd = maildir_create_tmp(mbox, ctx->tmpdir, &fname);
if (ctx->fd == -1) {
ctx->failed = TRUE;
t_pop();
More information about the dovecot-cvs
mailing list