diff options
author | Wayne Davison <wayned@samba.org> | 2013-05-26 14:52:50 -0700 |
---|---|---|
committer | Wayne Davison <wayned@samba.org> | 2013-05-26 16:22:56 -0700 |
commit | d4070db6312c4b38980ad165732d6beaaa0c06b3 (patch) | |
tree | 596623955444749ddeaf520a1eb2dd10c9021290 /io.c | |
parent | cb784f18ec02778419c58896cabbb418f5512ae1 (diff) | |
download | android_external_rsync-d4070db6312c4b38980ad165732d6beaaa0c06b3.tar.gz android_external_rsync-d4070db6312c4b38980ad165732d6beaaa0c06b3.tar.bz2 android_external_rsync-d4070db6312c4b38980ad165732d6beaaa0c06b3.zip |
Avoid I/O via signal-handler thread.
The cleanup code will try to flush the output buffer in some
circumstances, which is not valid if we're handling an async signal
(since it might have interrupted some partial I/O in the main thread).
These signals now set a flag and try to let the main I/O handler take
care of the exit strategy. Fixes a protocol error that could happen
when trying to exit after a kill signal.
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 12 |
1 files changed, 12 insertions, 0 deletions
@@ -57,6 +57,7 @@ extern int protocol_version; 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 @@ -73,6 +74,7 @@ BOOL flist_receiving_enabled = False; /* 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; @@ -852,6 +854,12 @@ static char *perform_io(size_t needed, int flags) } } + 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)) { @@ -2282,6 +2290,7 @@ void io_start_multiplex_out(int fd) 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; @@ -2329,6 +2338,9 @@ int io_end_multiplex_out(int mode) 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; } |