00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "rsync.h"
00023
00024 extern int am_sender;
00025 extern int am_server;
00026 extern int blocking_io;
00027 extern int filesfrom_fd;
00028 extern mode_t orig_umask;
00029 extern struct chmod_mode_struct *chmod_modes;
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 pid_t piped_child(char **command, int *f_in, int *f_out)
00045 {
00046 pid_t pid;
00047 int to_child_pipe[2];
00048 int from_child_pipe[2];
00049
00050 if (verbose >= 2) {
00051 print_child_argv(command);
00052 }
00053
00054 if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
00055 rsyserr(FERROR, errno, "pipe");
00056 exit_cleanup(RERR_IPC);
00057 }
00058
00059 pid = do_fork();
00060 if (pid == -1) {
00061 rsyserr(FERROR, errno, "fork");
00062 exit_cleanup(RERR_IPC);
00063 }
00064
00065 if (pid == 0) {
00066 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
00067 close(to_child_pipe[1]) < 0 ||
00068 close(from_child_pipe[0]) < 0 ||
00069 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
00070 rsyserr(FERROR, errno, "Failed to dup/close");
00071 exit_cleanup(RERR_IPC);
00072 }
00073 if (to_child_pipe[0] != STDIN_FILENO)
00074 close(to_child_pipe[0]);
00075 if (from_child_pipe[1] != STDOUT_FILENO)
00076 close(from_child_pipe[1]);
00077 umask(orig_umask);
00078 set_blocking(STDIN_FILENO);
00079 if (blocking_io > 0)
00080 set_blocking(STDOUT_FILENO);
00081 execvp(command[0], command);
00082 rsyserr(FERROR, errno, "Failed to exec %s", command[0]);
00083 exit_cleanup(RERR_IPC);
00084 }
00085
00086 if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0) {
00087 rsyserr(FERROR, errno, "Failed to close");
00088 exit_cleanup(RERR_IPC);
00089 }
00090
00091 *f_in = from_child_pipe[0];
00092 *f_out = to_child_pipe[1];
00093
00094 return pid;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
00108 int (*child_main)(int, char*[]))
00109 {
00110 pid_t pid;
00111 int to_child_pipe[2];
00112 int from_child_pipe[2];
00113
00114
00115 assert(am_sender);
00116
00117 if (fd_pair(to_child_pipe) < 0 ||
00118 fd_pair(from_child_pipe) < 0) {
00119 rsyserr(FERROR, errno, "pipe");
00120 exit_cleanup(RERR_IPC);
00121 }
00122
00123 pid = do_fork();
00124 if (pid == -1) {
00125 rsyserr(FERROR, errno, "fork");
00126 exit_cleanup(RERR_IPC);
00127 }
00128
00129 if (pid == 0) {
00130 am_sender = 0;
00131 am_server = 1;
00132 filesfrom_fd = -1;
00133 chmod_modes = NULL;
00134
00135 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
00136 close(to_child_pipe[1]) < 0 ||
00137 close(from_child_pipe[0]) < 0 ||
00138 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
00139 rsyserr(FERROR, errno, "Failed to dup/close");
00140 exit_cleanup(RERR_IPC);
00141 }
00142 if (to_child_pipe[0] != STDIN_FILENO)
00143 close(to_child_pipe[0]);
00144 if (from_child_pipe[1] != STDOUT_FILENO)
00145 close(from_child_pipe[1]);
00146 child_main(argc, argv);
00147 }
00148
00149 if (close(from_child_pipe[1]) < 0 ||
00150 close(to_child_pipe[0]) < 0) {
00151 rsyserr(FERROR, errno, "Failed to close");
00152 exit_cleanup(RERR_IPC);
00153 }
00154
00155 *f_in = from_child_pipe[0];
00156 *f_out = to_child_pipe[1];
00157
00158 return pid;
00159 }