Make exit_cleanup() use _exit() if called from a signal handler.
authorWayne Davison <wayned@samba.org>
Sun, 5 Apr 2020 17:26:40 +0000 (10:26 -0700)
committerWayne Davison <wayned@samba.org>
Sun, 5 Apr 2020 17:26:40 +0000 (10:26 -0700)
Fixes bug #13982.

cleanup.c
main.c
rsync.c

index 8cde03896f3150037fb92cddaf03b1386049148b..51130cafa570b931dcd6a393e079e46e55beef82 100644 (file)
--- a/cleanup.c
+++ b/cleanup.c
@@ -34,6 +34,7 @@ extern int output_needs_newline;
 extern char *partial_dir;
 extern char *logfile_name;
 
+int called_from_signal_handler = 0;
 BOOL shutting_down = False;
 BOOL flush_ok_after_signal = False;
 
@@ -260,6 +261,8 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
                break;
        }
 
+       if (called_from_signal_handler)
+               _exit(exit_code);
        exit(exit_code);
 }
 
diff --git a/main.c b/main.c
index f79054948ea521cfb5afed65d6638519553555dd..eda8d62459002f87083040b13a98f941b310ef99 100644 (file)
--- a/main.c
+++ b/main.c
@@ -39,6 +39,7 @@ extern int blocking_io;
 extern int always_checksum;
 extern int remove_source_files;
 extern int output_needs_newline;
+extern int called_from_signal_handler;
 extern int need_messages_from_generator;
 extern int kluge_around_eof;
 extern int got_xfer_error;
@@ -1536,6 +1537,7 @@ static int start_client(int argc, char *argv[])
 
 static void sigusr1_handler(UNUSED(int val))
 {
+       called_from_signal_handler = 1;
        exit_cleanup(RERR_SIGNAL1);
 }
 
diff --git a/rsync.c b/rsync.c
index 4d173037daf258a51e027850f5b96ccf3924fb55..b8d9acb90fd0370a4e24cbecc2ccf4cb71a0e5c1 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -43,6 +43,7 @@ extern int am_starting_up;
 extern int allow_8bit_chars;
 extern int protocol_version;
 extern int got_kill_signal;
+extern int called_from_signal_handler;
 extern int inc_recurse;
 extern int inplace;
 extern int flist_eof;
@@ -613,6 +614,8 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
 /* This is only called for SIGINT, SIGHUP, and SIGTERM. */
 void sig_int(int sig_num)
 {
+       called_from_signal_handler = 1;
+
        /* KLUGE: if the user hits Ctrl-C while ssh is prompting
         * for a password, then our cleanup's sending of a SIGUSR1
         * signal to all our children may kill ssh before it has a
@@ -636,6 +639,7 @@ void sig_int(int sig_num)
         * we didn't already set the flag. */
        if (!got_kill_signal && (am_server || am_receiver)) {
                got_kill_signal = sig_num;
+               called_from_signal_handler = 0;
                return;
        }