X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/adc4ebdd76cf98aacbe87b9664dd291199294297..f1ca7c4429f2a8e9de72f91d95218bb324df6a9e:/util.c diff --git a/util.c b/util.c index 2afb63ec..c4375175 100644 --- a/util.c +++ b/util.c @@ -275,38 +275,54 @@ int copy_file(const char *source, const char *dest, int ofd, int len; /* Number of bytes read into `buf'. */ if ((ifd = do_open(source, O_RDONLY, 0)) < 0) { + int save_errno = errno; rsyserr(FERROR_XFER, errno, "open %s", full_fname(source)); + errno = save_errno; return -1; } if (ofd < 0) { if (robust_unlink(dest) && errno != ENOENT) { + int save_errno = errno; rsyserr(FERROR_XFER, errno, "unlink %s", full_fname(dest)); + errno = save_errno; return -1; } - if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0 - && (!create_bak_dir || errno != ENOENT || make_bak_dir(dest) < 0 - || (ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0)) { - rsyserr(FERROR_XFER, errno, "open %s", full_fname(dest)); - close(ifd); - return -1; + if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0) { + int save_errno = errno ? errno : EINVAL; /* 0 paranoia */ + if (create_bak_dir && errno == ENOENT && make_bak_dir(dest) == 0) { + if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0) + save_errno = errno ? errno : save_errno; + else + save_errno = 0; + } + if (save_errno) { + rsyserr(FERROR_XFER, save_errno, "open %s", full_fname(dest)); + close(ifd); + errno = save_errno; + return -1; + } } } while ((len = safe_read(ifd, buf, sizeof buf)) > 0) { if (full_write(ofd, buf, len) < 0) { + int save_errno = errno; rsyserr(FERROR_XFER, errno, "write %s", full_fname(dest)); close(ifd); close(ofd); + errno = save_errno; return -1; } } if (len < 0) { + int save_errno = errno; rsyserr(FERROR_XFER, errno, "read %s", full_fname(source)); close(ifd); close(ofd); + errno = save_errno; return -1; } @@ -316,8 +332,10 @@ int copy_file(const char *source, const char *dest, int ofd, } if (close(ofd) < 0) { + int save_errno = errno; rsyserr(FERROR_XFER, errno, "close failed on %s", full_fname(dest)); + errno = save_errno; return -1; } @@ -401,8 +419,11 @@ int robust_rename(const char *from, const char *to, const char *partialptr, switch (errno) { #ifdef ETXTBSY case ETXTBSY: - if (robust_unlink(to) != 0) + if (robust_unlink(to) != 0) { + errno = ETXTBSY; return -1; + } + errno = ETXTBSY; break; #endif case EXDEV: