From: Daniel Lezcano Date: Thu, 28 May 2009 10:10:50 +0000 (+0200) Subject: make a "copy file" function X-Git-Tag: lxc_0_6_3~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e3642c43e6599fb1bfdd2e763e034c5c46299a46;p=thirdparty%2Flxc.git make a "copy file" function Create a specific function to copy a file from a location to another location. Signed-off-by: Daniel Lezcano --- diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am index 57b3caeb6..58c8ef384 100644 --- a/src/lxc/Makefile.am +++ b/src/lxc/Makefile.am @@ -34,7 +34,7 @@ liblxc_la_SOURCES = \ parse.c parse.h \ cgroup.c cgroup.h \ lxc.h \ - lxc_utils.h \ + utils.c utils.h \ lock.c lock.h \ namespace.h \ conf.c conf.h \ diff --git a/src/lxc/utils.c b/src/lxc/utils.c new file mode 100644 index 000000000..9a6b263c3 --- /dev/null +++ b/src/lxc/utils.c @@ -0,0 +1,104 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#include "log.h" + +lxc_log_define(lxc_utils, lxc); + +int lxc_copy_file(const char *srcfile, const char *dstfile) +{ + void *srcaddr = NULL, *dstaddr; + struct stat stat; + int srcfd, dstfd, ret = -1; + char c = '\0'; + + dstfd = open(dstfile, O_CREAT | O_EXCL | O_RDWR, 0600); + if (dstfd < 0) { + SYSERROR("failed to creat '%s'", dstfile); + goto out; + } + + srcfd = open(srcfile, O_RDONLY); + if (srcfd < 0) { + SYSERROR("failed to open '%s'", srcfile); + goto err; + } + + if (fstat(srcfd, &stat)) { + SYSERROR("failed to stat '%s'", srcfile); + goto err; + } + + if (!stat.st_size) { + INFO("copy '%s' which is an empty file", srcfile); + ret = 0; + goto out_close; + } + + if (lseek(dstfd, stat.st_size - 1, SEEK_SET) < 0) { + SYSERROR("failed to seek dest file '%s'", dstfile); + goto err; + } + + /* fixup length */ + if (write(dstfd, &c, 1) < 0) { + SYSERROR("failed to write to '%s'", dstfile); + goto err; + } + + srcaddr = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, srcfd, 0L); + if (srcaddr == MAP_FAILED) { + SYSERROR("failed to mmap '%s'", srcfile); + goto err; + } + + dstaddr = mmap(NULL, stat.st_size, PROT_WRITE, MAP_SHARED, dstfd, 0L); + if (dstaddr == MAP_FAILED) { + SYSERROR("failed to mmap '%s'", dstfile); + goto err; + } + + ret = 0; + + memcpy(dstaddr, srcaddr, stat.st_size); + + munmap(dstaddr, stat.st_size); +out_mmap: + if (srcaddr) + munmap(srcaddr, stat.st_size); +out_close: + close(dstfd); + close(srcfd); +out: + return ret; +err: + unlink(dstfile); + goto out_mmap; +} diff --git a/src/lxc/utils.h b/src/lxc/utils.h index 5fc3946fb..2fe078946 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -49,3 +49,5 @@ } while (0) #endif + +extern int lxc_copy_file(const char *src, const char *dst);