Use "use warnings" rather than -w on the #! line.
[rsync/rsync-patches.git] / catch_crash_signals.diff
CommitLineData
ae5c7864 1Igor Yu. Zhbanov wrote:
e2e42a01 2> I am using rsync compiled with Cygwin on windows.
ae5c7864
WD
3> I must call rsync from the *.bat script (I don't want to use a bash on Windows)
4> and I have noticed that in the case when program compiled by Cygwin crashes
5> via segmentation fault and default SIGSEGV handler is called, then it
6> terminates process with exit status 0 as I see it from my *.bat script.
7> (But if I invoke a program from bash (compiled with Cygwin too) I will see
8> error code 139 as expected.)
e2e42a01 9>
ae5c7864
WD
10> It is a Cygwin's problem, not an rsync's, but to use it on windows and
11> to distinguish situations when rsync crashes and when it exits normally,
12> I have written signal handler which terminates process with code 50.
13> You may use conventional 139. Also signal handler writes corresponding
14> message to log file.
e2e42a01 15>
ae5c7864
WD
16> By the way. When I terminate rsync in daemon mode by pressing Control-C,
17> it writes an error to log. May be this is not an error but info or notice?
18
19I'm not sure I like this, but if you run into the cygwin problem, this might
20prove helpful.
21
03019e41
WD
22To use this patch, run these commands for a successful build:
23
24 patch -p1 <patches/catch_crash_signals.diff
25 ./configure (optional if already run)
26 make
27
cc3e685d
WD
28diff --git a/errcode.h b/errcode.h
29--- a/errcode.h
30+++ b/errcode.h
ae5c7864 31@@ -47,6 +47,8 @@
ae5c7864 32 #define RERR_TIMEOUT 30 /* timeout in data send/receive */
cc3e685d 33 #define RERR_CONTIMEOUT 35 /* timeout waiting for daemon connection */
ae5c7864
WD
34
35+#define RERR_WECRASHED 50 /* We have crashed. */
36+
37 /* Although it doesn't seem to be specified anywhere,
38 * ssh and the shell seem to return these values:
39 *
cc3e685d
WD
40diff --git a/log.c b/log.c
41--- a/log.c
42+++ b/log.c
7f0bf1cb 43@@ -83,6 +83,7 @@ struct {
ae5c7864
WD
44 { RERR_TERMINATED , "sibling process terminated abnormally" },
45 { RERR_SIGNAL1 , "received SIGUSR1" },
46 { RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" },
47+ { RERR_WECRASHED , "rsync caught a CRASH-causing signal" },
48 { RERR_WAITCHILD , "waitpid() failed" },
49 { RERR_MALLOC , "error allocating core memory buffers" },
4c107044 50 { RERR_PARTIAL , "some files/attrs were not transferred (see previous errors)" },
cc3e685d
WD
51diff --git a/main.c b/main.c
52--- a/main.c
53+++ b/main.c
4c107044 54@@ -163,8 +163,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
ae5c7864
WD
55 *exit_code_ptr = RERR_TERMINATED;
56 else
57 *exit_code_ptr = RERR_WAITCHILD;
58- } else
59+ } else {
60 *exit_code_ptr = WEXITSTATUS(status);
61+ if (*exit_code_ptr == RERR_WECRASHED)
62+ *exit_code_ptr = RERR_CRASHED;
63+ }
64 }
65
66 /* This function gets called from all 3 processes. We want the client side
4c107044 67@@ -1315,6 +1318,14 @@ RETSIGTYPE remember_children(UNUSED(int val))
ae5c7864
WD
68 break;
69 }
70 }
71+ if (WIFSIGNALED(status)) {
72+ rprintf(FLOG,
73+ "rsync error: (1) Child proccess has unexpectedly died with signal %d\n",
74+ WTERMSIG(status));
75+ } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) {
76+ rprintf(FLOG,
77+ "rsync error: (1) Child proccess has CRASHED.\n");
78+ }
79 }
80 #endif
81 #ifndef HAVE_SIGACTION
4c107044 82@@ -1373,6 +1384,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
ae5c7864
WD
83 }
84 #endif
85
86+static RETSIGTYPE rsync_crash_handler(UNUSED(int whatsig))
87+{
88+ log_exit(RERR_WECRASHED, __FILE__, __LINE__);
89+ logfile_close();
90+ _exit(RERR_WECRASHED);
91+}
92
93 int main(int argc,char *argv[])
94 {
4c107044 95@@ -1395,6 +1412,11 @@ int main(int argc,char *argv[])
ae5c7864
WD
96 SIGACTMASK(SIGFPE, rsync_panic_handler);
97 SIGACTMASK(SIGABRT, rsync_panic_handler);
98 SIGACTMASK(SIGBUS, rsync_panic_handler);
99+#else
100+ SIGACTMASK(SIGSEGV, rsync_crash_handler);
101+ SIGACTMASK(SIGFPE, rsync_crash_handler);
102+ SIGACTMASK(SIGABRT, rsync_crash_handler);
103+ SIGACTMASK(SIGBUS, rsync_crash_handler);
104 #endif
105
106 starttime = time(NULL);
cc3e685d
WD
107diff --git a/socket.c b/socket.c
108--- a/socket.c
109+++ b/socket.c
e66d6d51 110@@ -518,7 +518,17 @@ int is_a_socket(int fd)
ae5c7864
WD
111 static RETSIGTYPE sigchld_handler(UNUSED(int val))
112 {
113 #ifdef WNOHANG
114- while (waitpid(-1, NULL, WNOHANG) > 0) {}
115+ int status;
116+ while (waitpid(-1, &status, WNOHANG) > 0) {
117+ if (WIFSIGNALED(status)) {
118+ rprintf(FLOG,
119+ "rsync error: (3) Child proccess has unexpectedly died with signal %d\n",
120+ WTERMSIG(status));
121+ } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) {
122+ rprintf(FLOG,
123+ "rsync error: (3) Child proccess has CRASHED.\n");
124+ }
125+ }
126 #endif
127 #ifndef HAVE_SIGACTION
128 signal(SIGCHLD, sigchld_handler);