From fe055c718ab5f3813d4e8b070b8b72dd9c2e0076 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 1 Jul 1998 11:03:50 +0000 Subject: [PATCH] - only keep a partial file if some literal data has been transferred, this prevents a second interrupted transfer from reducing the size of the transferred file. - set SIGUSR1 to SIG_IGN early to prevent a race condition that prevents the --partial code from working properly --- rsync.c | 59 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/rsync.c b/rsync.c index 7ad7a9ad..48ed69f8 100644 --- a/rsync.c +++ b/rsync.c @@ -53,6 +53,37 @@ extern int io_timeout; extern int io_error; extern struct stats stats; + +/* handling the cleanup when a transfer is interrupted is tricky when + --partial is selected. We need to ensure that the partial file is + kept if any real data has been transferred */ +static int cleanup_got_literal; +static char *cleanup_fname; +static char *cleanup_new_fname; +static struct file_struct *cleanup_file; +static void finish_transfer(char *fname, char *fnametmp, struct file_struct *file); + +void exit_cleanup(int code) +{ + extern int keep_partial; + + signal(SIGUSR1, SIG_IGN); + + if (cleanup_got_literal && cleanup_fname && keep_partial) { + char *fname = cleanup_fname; + cleanup_fname = NULL; + finish_transfer(cleanup_new_fname, fname, cleanup_file); + } + io_flush(); + if (cleanup_fname) + do_unlink(cleanup_fname); + if (code) { + kill_all(SIGUSR1); + } + exit(code); +} + + /* free a sums struct */ @@ -568,6 +599,8 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname) rprintf(FINFO,"data recv %d at %d\n",i,(int)offset); stats.literal_data += i; + cleanup_got_literal = 1; + sum_update(data,i); if (fd != -1 && write_file(fd,data,i) != i) { @@ -730,28 +763,6 @@ static void delete_files(struct file_list *flist) } } -static char *cleanup_fname; -static char *cleanup_new_fname; -static struct file_struct *cleanup_file; -static void finish_transfer(char *fname, char *fnametmp, struct file_struct *file); - -void exit_cleanup(int code) -{ - extern int keep_partial; - - if (cleanup_fname && keep_partial) { - finish_transfer(cleanup_new_fname, cleanup_fname, cleanup_file); - } - io_flush(); - if (cleanup_fname && !keep_partial) - do_unlink(cleanup_fname); - signal(SIGUSR1, SIG_IGN); - if (code) { - kill_all(SIGUSR1); - } - exit(code); -} - void sig_int(void) { exit_cleanup(1); @@ -860,7 +871,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) while (1) { cleanup_fname = NULL; - cleanup_new_fname = NULL; + cleanup_got_literal = 0; i = read_int(f_in); if (i == -1) { @@ -981,8 +992,6 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen) finish_transfer(fname, fnametmp, file); cleanup_fname = NULL; - cleanup_new_fname = NULL; - cleanup_file = NULL; if (!recv_ok) { if (csum_length == SUM_LENGTH) { -- 2.34.1