+ /* For pre-xfer exec, fork a child process to run the indicated
+ * command, though it first waits for the parent process to
+ * send us the user's request via a pipe. */
+ if (*lp_prexfer_exec(i)) {
+ int fds[2];
+ if (pipe(fds) < 0 || (pre_exec_pid = fork()) < 0) {
+ rsyserr(FLOG, errno, "pre-xfer exec preparation failed");
+ io_printf(f_out, "@ERROR: pre-xfer exec preparation failed\n");
+ return -1;
+ }
+ if (pre_exec_pid == 0) {
+ char buf[MAX_REQ_LEN+1];
+ int len;
+ close(fds[1]);
+ set_blocking(fds[0]);
+ len = read(fds[0], buf, MAX_REQ_LEN);
+ close(fds[0]);
+ if (len <= 0)
+ _exit(1);
+ buf[len] = '\0';
+ if (asprintf(&p, "RSYNC_REQUEST=%s", buf) < 0)
+ out_of_memory("rsync_module");
+ putenv(p);
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ status = system(lp_prexfer_exec(i));
+ if (!WIFEXITED(status))
+ _exit(1);
+ _exit(WEXITSTATUS(status));
+ }
+ close(fds[0]);
+ set_blocking(fds[1]);
+ pre_exec_fd = fds[1];
+ }