+ exit_cleanup(RERR_SYNTAX);
+ }
+
+ /* ... or no dest at all */
+ if (!am_sender && argc == 0)
+ list_only |= 1;
+
+ pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,
+ &f_in,&f_out);
+
+ /* if we're running an rsync server on the remote host over a
+ * remote shell command, we need to do the RSYNCD protocol first */
+ if (daemon_over_rsh) {
+ int tmpret;
+ tmpret = start_inband_exchange(shell_user, shell_path,
+ f_in, f_out, argc);
+ if (tmpret < 0)
+ return tmpret;
+ }
+
+ ret = client_run(f_in, f_out, pid, argc, argv);
+
+ fflush(stdout);
+ fflush(stderr);
+
+ return ret;
+}
+
+
+static RETSIGTYPE sigusr1_handler(UNUSED(int val))
+{
+ exit_cleanup(RERR_SIGNAL);
+}
+
+static RETSIGTYPE sigusr2_handler(UNUSED(int val))
+{
+ if (!am_server)
+ output_summary();
+ close_all();
+ if (log_got_error)
+ _exit(RERR_PARTIAL);
+ _exit(0);
+}
+
+static RETSIGTYPE sigchld_handler(UNUSED(int val))
+{
+#ifdef WNOHANG
+ int cnt, status;
+ pid_t pid;
+ /* An empty waitpid() loop was put here by Tridge and we could never
+ * get him to explain why he put it in, so rather than taking it
+ * out we're instead saving the child exit statuses for later use.
+ * The waitpid() loop presumably eliminates all possibility of leaving
+ * zombie children, maybe that's why he did it. */
+ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
+ /* save the child's exit status */
+ for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
+ if (pid_stat_table[cnt].pid == 0) {
+ pid_stat_table[cnt].pid = pid;
+ pid_stat_table[cnt].status = status;
+ break;
+ }
+ }
+ }