4 * Create a child connected to use on stdin/stdout.
6 * This is derived from CVS code
8 * Note that in the child STDIN is set to blocking and STDOUT
9 * is set to non-blocking. This is necessary as rsh relies on stdin being blocking
10 * and ssh relies on stdout being non-blocking
12 * If blocking_io is set then use blocking io on both fds. That can be
13 * used to cope with badly broken rsh implementations like the one on
16 pid_t piped_child(char **command, int *f_in, int *f_out)
20 int from_child_pipe[2];
21 extern int blocking_io;
24 print_child_argv(command);
27 if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
28 rprintf(FERROR, "pipe: %s\n", strerror(errno));
29 exit_cleanup(RERR_IPC);
35 rprintf(FERROR, "fork: %s\n", strerror(errno));
36 exit_cleanup(RERR_IPC);
40 extern int orig_umask;
41 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
42 close(to_child_pipe[1]) < 0 ||
43 close(from_child_pipe[0]) < 0 ||
44 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
45 rprintf(FERROR, "Failed to dup/close : %s\n",
47 exit_cleanup(RERR_IPC);
49 if (to_child_pipe[0] != STDIN_FILENO)
50 close(to_child_pipe[0]);
51 if (from_child_pipe[1] != STDOUT_FILENO)
52 close(from_child_pipe[1]);
54 set_blocking(STDIN_FILENO);
56 set_blocking(STDOUT_FILENO);
58 execvp(command[0], command);
59 rprintf(FERROR, "Failed to exec %s : %s\n",
60 command[0], strerror(errno));
61 exit_cleanup(RERR_IPC);
64 if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0) {
65 rprintf(FERROR, "Failed to close : %s\n", strerror(errno));
66 exit_cleanup(RERR_IPC);
69 *f_in = from_child_pipe[0];
70 *f_out = to_child_pipe[1];
75 pid_t local_child(int argc, char **argv,int *f_in,int *f_out,
76 int (*child_main)(int, char **))
80 int from_child_pipe[2];
81 extern int read_batch; /* dw */
83 if (fd_pair(to_child_pipe) < 0 ||
84 fd_pair(from_child_pipe) < 0) {
85 rprintf(FERROR,"pipe: %s\n",strerror(errno));
86 exit_cleanup(RERR_IPC);
92 rprintf(FERROR,"fork: %s\n",strerror(errno));
93 exit_cleanup(RERR_IPC);
100 am_sender = read_batch ? 0 : !am_sender;
103 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
104 close(to_child_pipe[1]) < 0 ||
105 close(from_child_pipe[0]) < 0 ||
106 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
107 rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
108 exit_cleanup(RERR_IPC);
110 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
111 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
112 child_main(argc, argv);
115 if (close(from_child_pipe[1]) < 0 ||
116 close(to_child_pipe[0]) < 0) {
117 rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
118 exit_cleanup(RERR_IPC);
121 *f_in = from_child_pipe[0];
122 *f_out = to_child_pipe[1];