+extern int blocking_io;
+extern int cvs_exclude;
+extern int delete_mode;
+extern int delete_excluded;
+extern int delete_after;
+extern int daemon_over_rsh;
+extern int do_stats;
+extern int dry_run;
+extern int list_only;
+extern int local_server;
+extern int log_got_error;
+extern int module_id;
+extern int orig_umask;
+extern int preserve_hard_links;
+extern int protocol_version;
+extern int recurse;
+extern int relative_paths;
+extern int rsync_port;
+extern int read_batch;
+extern int write_batch;
+extern int filesfrom_fd;
+extern pid_t cleanup_child_pid;
+extern char *files_from;
+extern char *remote_filesfrom_file;
+extern char *rsync_path;
+extern char *shell_cmd;
+extern struct file_list *batch_flist;
+
+
+/* there's probably never more than at most 2 outstanding child processes,
+ * but set it higher just in case.
+ */
+#define MAXCHILDPROCS 5
+
+struct pid_status {
+ pid_t pid;
+ int status;
+} pid_stat_table[MAXCHILDPROCS];
+
+static void show_malloc_stats(void);
+
+/****************************************************************************
+wait for a process to exit, calling io_flush while waiting
+****************************************************************************/
+void wait_process(pid_t pid, int *status)
+{
+ pid_t waited_pid;
+ int cnt;
+
+ while ((waited_pid = waitpid(pid, status, WNOHANG)) == 0) {
+ msleep(20);
+ io_flush(FULL_FLUSH);
+ }
+
+ if ((waited_pid == -1) && (errno == ECHILD)) {
+ /* status of requested child no longer available.
+ * check to see if it was processed by the sigchld_handler.
+ */
+ for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
+ if (pid == pid_stat_table[cnt].pid) {
+ *status = pid_stat_table[cnt].status;
+ pid_stat_table[cnt].pid = 0;
+ break;
+ }
+ }
+ }
+
+ /* 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 thhey know something went
+ * wrong. */
+ *status = WEXITSTATUS(*status);
+}