git
/
copy.c
72 строки · 1.4 Кб
1#include "git-compat-util.h"2#include "copy.h"3#include "path.h"4#include "gettext.h"5#include "strbuf.h"6#include "abspath.h"7
8int copy_fd(int ifd, int ofd)9{
10while (1) {11char buffer[8192];12ssize_t len = xread(ifd, buffer, sizeof(buffer));13if (!len)14break;15if (len < 0)16return COPY_READ_ERROR;17if (write_in_full(ofd, buffer, len) < 0)18return COPY_WRITE_ERROR;19}20return 0;21}
22
23static int copy_times(const char *dst, const char *src)24{
25struct stat st;26struct utimbuf times;27if (stat(src, &st) < 0)28return -1;29times.actime = st.st_atime;30times.modtime = st.st_mtime;31if (utime(dst, ×) < 0)32return -1;33return 0;34}
35
36int copy_file(const char *dst, const char *src, int mode)37{
38int fdi, fdo, status;39
40mode = (mode & 0111) ? 0777 : 0666;41if ((fdi = open(src, O_RDONLY)) < 0)42return fdi;43if ((fdo = open(dst, O_WRONLY | O_CREAT | O_EXCL, mode)) < 0) {44close(fdi);45return fdo;46}47status = copy_fd(fdi, fdo);48switch (status) {49case COPY_READ_ERROR:50error_errno("copy-fd: read returned");51break;52case COPY_WRITE_ERROR:53error_errno("copy-fd: write returned");54break;55}56close(fdi);57if (close(fdo) != 0)58return error_errno("%s: close error", dst);59
60if (!status && adjust_shared_perm(dst))61return -1;62
63return status;64}
65
66int copy_file_with_time(const char *dst, const char *src, int mode)67{
68int status = copy_file(dst, src, mode);69if (!status)70return copy_times(dst, src);71return status;72}
73