[dovecot-cvs] dovecot/src/lib Makefile.am, 1.62, 1.62.2.1 file-copy.c, NONE, 1.1.2.1 file-copy.h, NONE, 1.1.2.1

cras at dovecot.org cras at dovecot.org
Sat Jun 17 19:24:56 EEST 2006


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

Modified Files:
      Tag: branch_1_0
	Makefile.am 
Added Files:
      Tag: branch_1_0
	file-copy.c file-copy.h 
Log Message:
Added file_copy().



Index: Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/Makefile.am,v
retrieving revision 1.62
retrieving revision 1.62.2.1
diff -u -d -r1.62 -r1.62.2.1
--- Makefile.am	14 Apr 2006 10:26:55 -0000	1.62
+++ Makefile.am	17 Jun 2006 16:24:54 -0000	1.62.2.1
@@ -13,6 +13,7 @@
 	fd-set-nonblock.c \
 	fdpass.c \
 	file-cache.c \
+	file-copy.c \
 	file-dotlock.c \
 	file-lock.c \
 	file-set-size.c \
@@ -97,6 +98,7 @@
 	fd-set-nonblock.h \
 	fdpass.h \
 	file-cache.h \
+	file-copy.h \
 	file-dotlock.h \
 	file-lock.h \
 	file-set-size.h \

--- NEW FILE: file-copy.c ---
/* Copyright (c) 2006 Timo Sirainen */

#include "lib.h"
#include "istream.h"
#include "ostream.h"
#include "file-copy.h"

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int file_copy(const char *srcpath, const char *destpath, bool try_hardlink)
{
	const char *tmppath;
	struct istream *input;
	struct ostream *output;
	int fd_in, fd_out;
	off_t ret;

	if (try_hardlink) {
		/* see if hardlinking works */
		if (link(srcpath, destpath) == 0 || errno == EEXIST)
			return 1;
		if (errno == ENOENT)
			return 0;
		if (!ECANTLINK(errno)) {
			i_error("link(%s, %s) failed: %m", srcpath, destpath);
			return -1;
		}

		/* fallback to manual copying */
	}

	fd_in = open(srcpath, O_RDONLY);
	if (fd_in == -1) {
		if (errno == ENOENT)
			return 0;
		i_error("open(%s) failed: %m", srcpath);
		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);
	output = o_stream_create_file(fd_out, default_pool, 0, FALSE);

	while ((ret = o_stream_send_istream(output, input)) > 0) ;

	i_stream_destroy(&input);
	o_stream_destroy(&output);

	if (close(fd_in) < 0) {
		i_error("close(%s) failed: %m", srcpath);
		ret = -1;
	}
	if (close(fd_out) < 0) {
		i_error("close(%s) failed: %m", tmppath);
		ret = -1;
	}
	if (ret == 0) {
		if (rename(tmppath, destpath) < 0) {
			i_error("rename(%s, %s) failed: %m", tmppath, destpath);
			ret = -1;
		}
	}
	if (ret < 0)
		(void)unlink(tmppath);
	t_pop();
	return ret < 0 ? -1 : 1;
}

--- NEW FILE: file-copy.h ---
#ifndef __FILE_COPY_H
#define __FILE_COPY_H

/* Copy file atomically. First try hardlinking, then fallback to creating
   a temporary file (destpath.tmp) and rename()ing it over srcpath.
   If the destination file already exists, it may or may not be overwritten,
   so that shouldn't be relied on.

   Returns -1 = error, 0 = source file not found, 1 = ok */
int file_copy(const char *srcpath, const char *destpath, bool try_hardlink);

#endif



More information about the dovecot-cvs mailing list