X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib_internal%2Funify-copy.c;fp=lib_internal%2Funify-copy.c;h=0000000000000000000000000000000000000000;hb=db5ef3f969fc6ad34aeb5903e44d0049b2e50791;hp=c5c0062eaaf539975fcad25b138423329ae28ef6;hpb=95e2774070e989fe9cf9f48dae5fa054e55e2a3e;p=util-vserver.git diff --git a/lib_internal/unify-copy.c b/lib_internal/unify-copy.c deleted file mode 100644 index c5c0062..0000000 --- a/lib_internal/unify-copy.c +++ /dev/null @@ -1,239 +0,0 @@ -// $Id: unify-copy.c 2544 2007-06-01 16:16:33Z ensc $ --*- c -*-- - -// Copyright (C) 2004 Enrico Scholz -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; version 2 of the License. -// -// This program 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "unify.h" -#include "util.h" - -#include -#include -#include -#include -#include -#include -#include - -#define ENSC_WRAPPERS_IO 1 -#include - -#define MMAP_BLOCKSIZE (16 * 1024*1024) - -#ifndef TESTSUITE_COPY_CODE -# define TESTSUITE_COPY_CODE do { } while (false) -#endif - -static inline bool -verifySource(int fd, struct stat const *exp_stat) -{ - struct stat st; - - return (fstat(fd, &st)!=-1 && - st.st_dev==exp_stat->st_dev && - st.st_ino==exp_stat->st_ino); -} - -static inline bool -copyLnk(char const *src, char const *dst) -{ - ssize_t len = 1024; - for (;;) { - char buf[len]; - ssize_t l; - l = readlink(src, buf, len-1); - if (l==-1) return false; - if (l>=len-1) { - len *= 2; - continue; - } - buf[l] = '\0'; - - return (symlink(buf, dst)!=-1); - } -} - -static sigjmp_buf bus_error_restore; -static volatile sig_atomic_t bus_error; - -static void -handlerSIGBUS(int UNUSED num) -{ - bus_error = 1; - siglongjmp(bus_error_restore, 1); -} - -static void -copyMem(void *dst_v, void const *src_v, size_t len_v) -{ -#if 1 - // Do not use memcpy because this would dirty pages consisting only of - // '\0' - int *dst = dst_v; - int const *src = src_v; - size_t len = len_v / sizeof(int); - size_t rest = len_v - sizeof(int)*len; - size_t i=0; - - for (; i0 && ftruncate(out_fd, in_len)==-1) // create sparse file - return false; - - bus_error = 0; - if (sigsetjmp(bus_error_restore, 1)==0) { - off_t offset = 0; - - while (offset < in_len) { - buf_size = in_len - offset; - if (buf_size > MMAP_BLOCKSIZE) buf_size = MMAP_BLOCKSIZE; - - if ((in_buf = mmap(0, buf_size, PROT_READ, MAP_SHARED, in_fd, offset))==0 || - (out_buf = mmap(0, buf_size, PROT_WRITE, MAP_SHARED, out_fd, offset))==0) { - perror("mmap()"); - goto out; - } - - offset += buf_size; - madvise(const_cast(void *)(in_buf), buf_size, MADV_SEQUENTIAL); - madvise(out_buf, buf_size, MADV_SEQUENTIAL); - - TESTSUITE_COPY_CODE; - copyMem(out_buf, in_buf, buf_size); - - munmap(out_buf, buf_size); out_buf = 0; - munmap(const_cast(void *)(in_buf), buf_size); in_buf = 0; - } - - res = true; - } - - out: - if (out_buf!=0) munmap(out_buf, buf_size); - if (in_buf !=0) munmap(const_cast(void *)(in_buf), buf_size); - - return res; -} - -static inline bool -copyReg(char const *src, struct stat const *src_stat, - char const *dst) -{ - int in_fd = open(src, O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_LARGEFILE); - int out_fd = in_fd==-1 ? -1 : open(dst, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY, 0200); - bool res = false; - - if (in_fd==-1 || out_fd==-1 || - !verifySource(in_fd, src_stat)) goto err; - -#if 0 - for (;;) { - char buf[2048]; - ssize_t l = read(in_fd, buf, sizeof buf); - if (l==-1) goto err; - if (l==0) break; - if (!WwriteAll(out_fd, buf, l, 0)) goto err; - } - - res = true; -#else - void (*old_handler)(int) = signal(SIGBUS, handlerSIGBUS); - - res = copyMMap(in_fd, out_fd); - - signal(SIGBUS, old_handler); -#endif - - err: - if (out_fd!=-1 && close(out_fd)==-1) res=false; - if (in_fd!=-1 && close(in_fd)==-1) res=false; - return res; -} - -static inline bool -copyNode(char const UNUSED *src, struct stat const *src_stat, - char const *dst) -{ - return mknod(dst, src_stat->st_mode & (S_IFMT|S_IWUSR), - src_stat->st_rdev)!=-1; -} - -static inline bool -copyDir(char const UNUSED *src, struct stat const UNUSED *src_stat, - char const *dst) -{ - return mkdir(dst, 0700)!=-1; -} - -static inline bool -setModes(char const *path, struct stat const *st) -{ - return (lchown(path, st->st_uid, st->st_gid)!=-1 && - (S_ISLNK(st->st_mode) || chmod(path, st->st_mode)!=-1)); -} - - -bool -Unify_copy(char const *src, struct stat const *src_stat, - char const *dst) -{ - // skip sockets - // TODO: message - if (S_ISSOCK(src_stat->st_mode)) - return true; - - return - (((S_ISLNK (src_stat->st_mode) && copyLnk (src, dst)) || - (S_ISREG (src_stat->st_mode) && copyReg (src, src_stat, dst)) || - (S_ISDIR (src_stat->st_mode) && copyDir (src, src_stat, dst)) || - ((S_ISBLK (src_stat->st_mode) || - S_ISCHR (src_stat->st_mode) || - S_ISFIFO(src_stat->st_mode)) && copyNode(src, src_stat, dst)) - ) && - setModes(dst, src_stat) && - Unify_setTime(dst, src_stat)); -}