aboutsummaryrefslogtreecommitdiffstats
path: root/cleanup.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2013-05-26 14:52:50 -0700
committerWayne Davison <wayned@samba.org>2013-05-26 16:22:56 -0700
commitd4070db6312c4b38980ad165732d6beaaa0c06b3 (patch)
tree596623955444749ddeaf520a1eb2dd10c9021290 /cleanup.c
parentcb784f18ec02778419c58896cabbb418f5512ae1 (diff)
downloadandroid_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 'cleanup.c')
-rw-r--r--cleanup.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/cleanup.c b/cleanup.c
index 9de6eab8..971154ce 100644
--- a/cleanup.c
+++ b/cleanup.c
@@ -34,6 +34,7 @@ extern char *partial_dir;
extern char *logfile_name;
BOOL shutting_down = False;
+BOOL flush_ok_after_signal = False;
#ifdef HAVE_SIGACTION
static struct sigaction sigact;
@@ -182,7 +183,12 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
#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 */