X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=copy.c;h=a7f58fd905b31b2634f74580090ec664a640e279;hb=6b37dff17f176d7e87efa93b4cf521dd725de247;hp=c225d1b0ff0a67e637f7200ab5c2a917b550af4f;hpb=f124e986cf19e8f36895ae474d50f8d389e73d02;p=git.git diff --git a/copy.c b/copy.c index c225d1b0f..a7f58fd90 100644 --- a/copy.c +++ b/copy.c @@ -9,8 +9,7 @@ int copy_fd(int ifd, int ofd) if (!len) break; if (len < 0) { - int read_error; - read_error = errno; + int read_error = errno; close(ifd); return error("copy-fd: read returned %s", strerror(read_error)); @@ -25,12 +24,55 @@ int copy_fd(int ifd, int ofd) close(ifd); return error("copy-fd: write returned 0"); } else { + int write_error = errno; close(ifd); return error("copy-fd: write returned %s", - strerror(errno)); + strerror(write_error)); } } } close(ifd); return 0; } + +static int copy_times(const char *dst, const char *src) +{ + struct stat st; + struct utimbuf times; + if (stat(src, &st) < 0) + return -1; + times.actime = st.st_atime; + times.modtime = st.st_mtime; + if (utime(dst, ×) < 0) + return -1; + return 0; +} + +int copy_file(const char *dst, const char *src, int mode) +{ + int fdi, fdo, status; + + mode = (mode & 0111) ? 0777 : 0666; + if ((fdi = open(src, O_RDONLY)) < 0) + return fdi; + if ((fdo = open(dst, O_WRONLY | O_CREAT | O_EXCL, mode)) < 0) { + close(fdi); + return fdo; + } + status = copy_fd(fdi, fdo); + if (close(fdo) != 0) + return error("%s: close error: %s", dst, strerror(errno)); + + if (!status && adjust_shared_perm(dst)) + return -1; + + return status; +} + +int copy_file_with_time(const char *dst, const char *src, int mode) +{ + int status = copy_file(dst, src, mode); + if (!status) + return copy_times(dst, src); + return status; +}