#include "rsync.h"
extern int am_sender;
extern int am_server;
extern int blocking_io;
extern int filesfrom_fd;
extern mode_t orig_umask;
extern char *logfile_name;
extern struct chmod_mode_struct *chmod_modes;
pid_t piped_child(char **command, int *f_in, int *f_out)
{
pid_t pid;
int to_child_pipe[2];
int from_child_pipe[2];
if (verbose >= 2) {
print_child_argv(command);
}
if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
rsyserr(FERROR, errno, "pipe");
exit_cleanup(RERR_IPC);
}
pid = do_fork();
if (pid == -1) {
rsyserr(FERROR, errno, "fork");
exit_cleanup(RERR_IPC);
}
if (pid == 0) {
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
close(to_child_pipe[1]) < 0 ||
close(from_child_pipe[0]) < 0 ||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
rsyserr(FERROR, errno, "Failed to dup/close");
exit_cleanup(RERR_IPC);
}
if (to_child_pipe[0] != STDIN_FILENO)
close(to_child_pipe[0]);
if (from_child_pipe[1] != STDOUT_FILENO)
close(from_child_pipe[1]);
umask(orig_umask);
set_blocking(STDIN_FILENO);
if (blocking_io > 0)
set_blocking(STDOUT_FILENO);
execvp(command[0], command);
rsyserr(FERROR, errno, "Failed to exec %s", command[0]);
exit_cleanup(RERR_IPC);
}
if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0) {
rsyserr(FERROR, errno, "Failed to close");
exit_cleanup(RERR_IPC);
}
*f_in = from_child_pipe[0];
*f_out = to_child_pipe[1];
return pid;
}
pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
int (*child_main)(int, char*[]))
{
pid_t pid;
int to_child_pipe[2];
int from_child_pipe[2];
assert(am_sender);
if (fd_pair(to_child_pipe) < 0 ||
fd_pair(from_child_pipe) < 0) {
rsyserr(FERROR, errno, "pipe");
exit_cleanup(RERR_IPC);
}
pid = do_fork();
if (pid == -1) {
rsyserr(FERROR, errno, "fork");
exit_cleanup(RERR_IPC);
}
if (pid == 0) {
am_sender = 0;
am_server = 1;
filesfrom_fd = -1;
chmod_modes = NULL;
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
close(to_child_pipe[1]) < 0 ||
close(from_child_pipe[0]) < 0 ||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
rsyserr(FERROR, errno, "Failed to dup/close");
exit_cleanup(RERR_IPC);
}
if (to_child_pipe[0] != STDIN_FILENO)
close(to_child_pipe[0]);
if (from_child_pipe[1] != STDOUT_FILENO)
close(from_child_pipe[1]);
child_main(argc, argv);
}
if (logfile_name) {
logfile_name = NULL;
logfile_close();
}
if (close(from_child_pipe[1]) < 0 ||
close(to_child_pipe[0]) < 0) {
rsyserr(FERROR, errno, "Failed to close");
exit_cleanup(RERR_IPC);
}
*f_in = from_child_pipe[0];
*f_out = to_child_pipe[1];
return pid;
}