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();