+ while ((waited_pid = wait_process(pid, &status, WNOHANG)) == 0) {
+ msleep(20);
+ io_flush(FULL_FLUSH);
+ }
+
+ /* TODO: If the child exited on a signal, then log an
+ * appropriate error message. Perhaps we should also accept a
+ * message describing the purpose of the child. Also indicate
+ * this to the caller so that they know something went wrong. */
+ if (waited_pid < 0) {
+ rsyserr(FERROR, errno, "waitpid");
+ *exit_code_ptr = RERR_WAITCHILD;
+ } else if (!WIFEXITED(status)) {
+#ifdef WCOREDUMP
+ if (WCOREDUMP(status))
+ *exit_code_ptr = RERR_CRASHED;
+ else
+#endif
+ if (WIFSIGNALED(status))
+ *exit_code_ptr = RERR_TERMINATED;
+ else
+ *exit_code_ptr = RERR_WAITCHILD;
+ } else
+ *exit_code_ptr = WEXITSTATUS(status);
+}
+
+/* This function gets called from all 3 processes. We want the client side
+ * to actually output the text, but the sender is the only process that has
+ * all the stats we need. So, if we're a client sender, we do the report.
+ * If we're a server sender, we write the stats on the supplied fd. If
+ * we're the client receiver we read the stats from the supplied fd and do
+ * the report. All processes might also generate a set of debug stats, if
+ * the verbose level is high enough (this is the only thing that the
+ * generator process and the server receiver ever do here). */
+static void handle_stats(int f)
+{
+ endtime = time(NULL);
+
+ /* Cache two stats because the read/write code can change it. */
+ total_read = stats.total_read;
+ total_written = stats.total_written;
+
+ if (do_stats && verbose > 1) {