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