extern char *logfile_name;
BOOL shutting_down = False;
+BOOL flush_ok_after_signal = False;
#ifdef HAVE_SIGACTION
static struct sigaction sigact;
#include "case_N.h"
switch_step++;
- if (!code || am_server || am_receiver)
+ if (flush_ok_after_signal) {
+ flush_ok_after_signal = False;
+ if (code == RERR_SIGNAL)
+ io_flush(FULL_FLUSH);
+ }
+ if (!code)
io_flush(FULL_FLUSH);
/* FALLTHROUGH */
extern int remove_source_files;
extern int preserve_hard_links;
extern BOOL extra_flist_sending_enabled;
+extern BOOL flush_ok_after_signal;
extern struct stats stats;
extern struct file_list *cur_flist;
#ifdef ICONV_OPTION
/* Ignore an EOF error if non-zero. See whine_about_eof(). */
int kluge_around_eof = 0;
+int got_kill_signal = -1; /* is set to 0 only after multiplexed I/O starts */
int sock_f_in = -1;
int sock_f_out = -1;
}
}
+ if (got_kill_signal > 0) {
+ got_kill_signal = -1;
+ flush_ok_after_signal = True;
+ exit_cleanup(RERR_SIGNAL);
+ }
+
/* We need to help prevent deadlock by doing what reading
* we can whenever we are here trying to write. */
if (IN_MULTIPLEXED_AND_READY && !(flags & PIO_NEED_INPUT)) {
iobuf.out_empty_len = 4; /* See also OUT_MULTIPLEXED */
io_start_buffering_out(fd);
+ got_kill_signal = 0;
iobuf.raw_data_header_pos = iobuf.out.pos + iobuf.out.len;
iobuf.out.len += 4;
iobuf.out.len = 0;
iobuf.out_empty_len = 0;
+ if (got_kill_signal > 0) /* Just in case... */
+ exit_cleanup(RERR_SIGNAL);
+ got_kill_signal = -1;
return ret;
}
extern int am_starting_up;
extern int allow_8bit_chars;
extern int protocol_version;
+extern int got_kill_signal;
extern int inc_recurse;
extern int inplace;
extern int flist_eof;
return updated;
}
+/* This is only called for SIGINT, SIGHUP, and SIGTERM. */
RETSIGTYPE sig_int(int sig_num)
{
/* KLUGE: if the user hits Ctrl-C while ssh is prompting
* not ssh waiting for a password, then this tiny delay
* shouldn't hurt anything. */
msleep(400);
+
/* If we're an rsync daemon listener (not a daemon server),
* we'll exit with status 0 if we received SIGTERM. */
if (am_daemon && !am_server && sig_num == SIGTERM)
exit_cleanup(0);
+
+ /* If the signal arrived on the server side (or for the receiver
+ * process on the client), we want to try to do a controlled shutdown
+ * that lets the client side (generator process) know what happened.
+ * To do this, we set a flag and let the normal process handle the
+ * shutdown. We only attempt this if multiplexed IO is in effect and
+ * we didn't already set the flag. */
+ if (!got_kill_signal && (am_server || am_receiver)) {
+ got_kill_signal = sig_num;
+ return;
+ }
+
exit_cleanup(RERR_SIGNAL);
}