From 4d4cada65a09dd40940aa021ba7a52b5fbf266be Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 9 Oct 2014 09:34:11 +0100 Subject: [PATCH] daemon: copy-file-to-file: Unlink destination file on failure (RHBZ#1150867). When copying from file to file, don't leave the destination file around if the copy fails. However in the same code don't try unlinking the destination device on failure. --- daemon/copy.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/daemon/copy.c b/daemon/copy.c index 9312e51d0..bab00fe9a 100644 --- a/daemon/copy.c +++ b/daemon/copy.c @@ -29,9 +29,13 @@ #include "daemon.h" #include "actions.h" +/* wrflags */ #define DEST_FILE_FLAGS O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY|O_CLOEXEC, 0666 #define DEST_DEVICE_FLAGS O_WRONLY|O_CLOEXEC, 0 +/* flags */ +#define COPY_UNLINK_DEST_ON_FAILURE 1 + /* NB: We cheat slightly by assuming that optargs_bitmask is * compatible for all four of the calls. This is true provided they * all take the same set of optional arguments. @@ -42,6 +46,7 @@ static int copy (const char *src, const char *src_display, const char *dest, const char *dest_display, int wrflags, int wrmode, + int flags, int64_t srcoffset, int64_t destoffset, int64_t size, int sparse) { int64_t saved_size = size; @@ -105,6 +110,8 @@ copy (const char *src, const char *src_display, reply_with_perror ("lseek: %s", dest_display); close (src_fd); close (dest_fd); + if (flags & COPY_UNLINK_DEST_ON_FAILURE) + unlink (dest); return -1; } @@ -127,6 +134,8 @@ copy (const char *src, const char *src_display, reply_with_perror ("read: %s", src_display); close (src_fd); close (dest_fd); + if (flags & COPY_UNLINK_DEST_ON_FAILURE) + unlink (dest); return -1; } @@ -136,6 +145,8 @@ copy (const char *src, const char *src_display, reply_with_error ("%s: input too short", src_display); close (src_fd); close (dest_fd); + if (flags & COPY_UNLINK_DEST_ON_FAILURE) + unlink (dest); return -1; } @@ -148,6 +159,8 @@ copy (const char *src, const char *src_display, reply_with_perror ("%s: seek (because of sparse flag)", dest_display); close (src_fd); close (dest_fd); + if (flags & COPY_UNLINK_DEST_ON_FAILURE) + unlink (dest); return -1; } goto sparse_skip; @@ -161,6 +174,8 @@ copy (const char *src, const char *src_display, reply_with_perror ("%s: write", dest_display); close (src_fd); close (dest_fd); + if (flags & COPY_UNLINK_DEST_ON_FAILURE) + unlink (dest); return -1; } sparse_skip: @@ -177,11 +192,15 @@ copy (const char *src, const char *src_display, if (close (src_fd) == -1) { reply_with_perror ("close: %s", src_display); close (dest_fd); + if (flags & COPY_UNLINK_DEST_ON_FAILURE) + unlink (dest); return -1; } if (close (dest_fd) == -1) { reply_with_perror ("close: %s", dest_display); + if (flags & COPY_UNLINK_DEST_ON_FAILURE) + unlink (dest); return -1; } @@ -193,7 +212,7 @@ do_copy_device_to_device (const char *src, const char *dest, int64_t srcoffset, int64_t destoffset, int64_t size, int sparse) { - return copy (src, src, dest, dest, DEST_DEVICE_FLAGS, + return copy (src, src, dest, dest, DEST_DEVICE_FLAGS, 0, srcoffset, destoffset, size, sparse); } @@ -209,7 +228,7 @@ do_copy_device_to_file (const char *src, const char *dest, return -1; } - return copy (src, src, dest_buf, dest, DEST_FILE_FLAGS, + return copy (src, src, dest_buf, dest, DEST_FILE_FLAGS, 0, srcoffset, destoffset, size, sparse); } @@ -225,7 +244,7 @@ do_copy_file_to_device (const char *src, const char *dest, return -1; } - return copy (src_buf, src, dest, dest, DEST_DEVICE_FLAGS, + return copy (src_buf, src, dest, dest, DEST_DEVICE_FLAGS, 0, srcoffset, destoffset, size, sparse); } @@ -249,5 +268,6 @@ do_copy_file_to_file (const char *src, const char *dest, } return copy (src_buf, src, dest_buf, dest, DEST_FILE_FLAGS, + COPY_UNLINK_DEST_ON_FAILURE, srcoffset, destoffset, size, sparse); }