Mercurial > dovecot > original-hg > dovecot-1.2
changeset 5906:47d0899be687 HEAD
When checking if destination temp file exists, if stat() failed with anything
else than ENOENT, we got stuck infinitely.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 08 Jul 2007 21:35:17 +0300 |
parents | 81b3a22e6ce1 |
children | 2596602b6bd1 |
files | src/lib-storage/index/maildir/maildir-save.c |
diffstat | 1 files changed, 15 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ } 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 @@ /* 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 @@ 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();