[dovecot-cvs] dovecot/src/lib file-copy.c,1.2,1.3

cras at dovecot.org cras at dovecot.org
Mon Jun 19 21:16:02 EEST 2006


Update of /var/lib/cvs/dovecot/src/lib
In directory talvi:/tmp/cvs-serv13554

Modified Files:
	file-copy.c 
Log Message:
If destination file already existed, we didn't overwrite it with link()
copying.



Index: file-copy.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/file-copy.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- file-copy.c	17 Jun 2006 16:24:55 -0000	1.2
+++ file-copy.c	19 Jun 2006 18:15:59 -0000	1.3
@@ -9,9 +9,9 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-int file_copy(const char *srcpath, const char *destpath, bool try_hardlink)
+static int file_copy_to_tmp(const char *srcpath, const char *tmppath,
+			    bool try_hardlink)
 {
-	const char *tmppath;
 	struct istream *input;
 	struct ostream *output;
 	int fd_in, fd_out;
@@ -19,12 +19,20 @@
 
 	if (try_hardlink) {
 		/* see if hardlinking works */
-		if (link(srcpath, destpath) == 0 || errno == EEXIST)
+		if (link(srcpath, tmppath) == 0)
 			return 1;
+		if (errno == EEXIST) {
+			if (unlink(tmppath) < 0 && errno != ENOENT) {
+				i_error("unlink(%s) failed: %m", tmppath);
+				return -1;
+			}
+			if (link(srcpath, tmppath) == 0)
+				return 1;
+		}
 		if (errno == ENOENT)
 			return 0;
 		if (!ECANTLINK(errno)) {
-			i_error("link(%s, %s) failed: %m", srcpath, destpath);
+			i_error("link(%s, %s) failed: %m", srcpath, tmppath);
 			return -1;
 		}
 
@@ -39,13 +47,10 @@
 		return -1;
 	}
 
-	t_push();
-	tmppath = t_strconcat(destpath, ".tmp", NULL);
 	fd_out = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0644);
 	if (fd_out == -1) {
 		i_error("open(%s, O_CREAT) failed: %m", tmppath);
 		(void)close(fd_in);
-		t_pop();
 		return -1;
 	}
 	input = i_stream_create_file(fd_in, default_pool, 0, FALSE);
@@ -64,7 +69,19 @@
 		i_error("close(%s) failed: %m", tmppath);
 		ret = -1;
 	}
-	if (ret == 0) {
+	return ret < 0 ? -1 : 1;
+}
+
+int file_copy(const char *srcpath, const char *destpath, bool try_hardlink)
+{
+	const char *tmppath;
+	int ret;
+
+	t_push();
+	tmppath = t_strconcat(destpath, ".tmp", NULL);
+
+	ret = file_copy_to_tmp(srcpath, tmppath, try_hardlink);
+	if (ret > 0) {
 		if (rename(tmppath, destpath) < 0) {
 			i_error("rename(%s, %s) failed: %m", tmppath, destpath);
 			ret = -1;
@@ -72,6 +89,7 @@
 	}
 	if (ret < 0)
 		(void)unlink(tmppath);
+
 	t_pop();
-	return ret < 0 ? -1 : 1;
+	return ret;
 }



More information about the dovecot-cvs mailing list