Commit | Line | Data |
---|---|---|
ae5c7864 WD |
1 | Igor Yu. Zhbanov wrote: |
2 | > I am using rsync compiled with Cygwin on windows. | |
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.) | |
9 | > | |
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. | |
15 | > | |
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 | ||
19 | I'm not sure I like this, but if you run into the cygwin problem, this might | |
20 | prove helpful. | |
21 | ||
22 | --- old/errcode.h | |
23 | +++ new/errcode.h | |
24 | @@ -47,6 +47,8 @@ | |
25 | ||
26 | #define RERR_TIMEOUT 30 /* timeout in data send/receive */ | |
27 | ||
28 | +#define RERR_WECRASHED 50 /* We have crashed. */ | |
29 | + | |
30 | /* Although it doesn't seem to be specified anywhere, | |
31 | * ssh and the shell seem to return these values: | |
32 | * | |
33 | --- old/log.c | |
34 | +++ new/log.c | |
35 | @@ -77,6 +77,7 @@ struct { | |
36 | { RERR_TERMINATED , "sibling process terminated abnormally" }, | |
37 | { RERR_SIGNAL1 , "received SIGUSR1" }, | |
38 | { RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" }, | |
39 | + { RERR_WECRASHED , "rsync caught a CRASH-causing signal" }, | |
40 | { RERR_WAITCHILD , "waitpid() failed" }, | |
41 | { RERR_MALLOC , "error allocating core memory buffers" }, | |
42 | { RERR_PARTIAL , "some files could not be transferred" }, | |
43 | --- old/main.c | |
44 | +++ new/main.c | |
45 | @@ -137,8 +137,11 @@ static void wait_process_with_flush(pid_ | |
46 | *exit_code_ptr = RERR_TERMINATED; | |
47 | else | |
48 | *exit_code_ptr = RERR_WAITCHILD; | |
49 | - } else | |
50 | + } else { | |
51 | *exit_code_ptr = WEXITSTATUS(status); | |
52 | + if (*exit_code_ptr == RERR_WECRASHED) | |
53 | + *exit_code_ptr = RERR_CRASHED; | |
54 | + } | |
55 | } | |
56 | ||
57 | /* This function gets called from all 3 processes. We want the client side | |
58 | @@ -1112,6 +1115,14 @@ static RETSIGTYPE sigchld_handler(UNUSED | |
59 | break; | |
60 | } | |
61 | } | |
62 | + if (WIFSIGNALED(status)) { | |
63 | + rprintf(FLOG, | |
64 | + "rsync error: (1) Child proccess has unexpectedly died with signal %d\n", | |
65 | + WTERMSIG(status)); | |
66 | + } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) { | |
67 | + rprintf(FLOG, | |
68 | + "rsync error: (1) Child proccess has CRASHED.\n"); | |
69 | + } | |
70 | } | |
71 | #endif | |
72 | #ifndef HAVE_SIGACTION | |
73 | @@ -1170,6 +1181,12 @@ static RETSIGTYPE rsync_panic_handler(UN | |
74 | } | |
75 | #endif | |
76 | ||
77 | +static RETSIGTYPE rsync_crash_handler(UNUSED(int whatsig)) | |
78 | +{ | |
79 | + log_exit(RERR_WECRASHED, __FILE__, __LINE__); | |
80 | + logfile_close(); | |
81 | + _exit(RERR_WECRASHED); | |
82 | +} | |
83 | ||
84 | int main(int argc,char *argv[]) | |
85 | { | |
86 | @@ -1192,6 +1209,11 @@ int main(int argc,char *argv[]) | |
87 | SIGACTMASK(SIGFPE, rsync_panic_handler); | |
88 | SIGACTMASK(SIGABRT, rsync_panic_handler); | |
89 | SIGACTMASK(SIGBUS, rsync_panic_handler); | |
90 | +#else | |
91 | + SIGACTMASK(SIGSEGV, rsync_crash_handler); | |
92 | + SIGACTMASK(SIGFPE, rsync_crash_handler); | |
93 | + SIGACTMASK(SIGABRT, rsync_crash_handler); | |
94 | + SIGACTMASK(SIGBUS, rsync_crash_handler); | |
95 | #endif | |
96 | ||
97 | starttime = time(NULL); | |
98 | --- old/socket.c | |
99 | +++ new/socket.c | |
100 | @@ -435,7 +435,17 @@ int is_a_socket(int fd) | |
101 | static RETSIGTYPE sigchld_handler(UNUSED(int val)) | |
102 | { | |
103 | #ifdef WNOHANG | |
104 | - while (waitpid(-1, NULL, WNOHANG) > 0) {} | |
105 | + int status; | |
106 | + while (waitpid(-1, &status, WNOHANG) > 0) { | |
107 | + if (WIFSIGNALED(status)) { | |
108 | + rprintf(FLOG, | |
109 | + "rsync error: (3) Child proccess has unexpectedly died with signal %d\n", | |
110 | + WTERMSIG(status)); | |
111 | + } else if (WIFEXITED(status) && WEXITSTATUS(status) == RERR_WECRASHED) { | |
112 | + rprintf(FLOG, | |
113 | + "rsync error: (3) Child proccess has CRASHED.\n"); | |
114 | + } | |
115 | + } | |
116 | #endif | |
117 | #ifndef HAVE_SIGACTION | |
118 | signal(SIGCHLD, sigchld_handler); |