Commit | Line | Data |
---|---|---|
b35d0d8e MP |
1 | #include "rsync.h" |
2 | ||
3 | /** | |
4 | * Create a child connected to use on stdin/stdout. | |
5 | * | |
6 | * This is derived from CVS code | |
7 | * | |
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 | |
11 | * | |
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 | |
14 | * Solaris. | |
15 | **/ | |
16 | pid_t piped_child(char **command, int *f_in, int *f_out) | |
17 | { | |
18 | pid_t pid; | |
19 | int to_child_pipe[2]; | |
20 | int from_child_pipe[2]; | |
21 | extern int blocking_io; | |
22 | ||
23 | if (verbose >= 2) { | |
24 | print_child_argv(command); | |
25 | } | |
26 | ||
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); | |
30 | } | |
31 | ||
32 | ||
33 | pid = do_fork(); | |
34 | if (pid == -1) { | |
35 | rprintf(FERROR, "fork: %s\n", strerror(errno)); | |
36 | exit_cleanup(RERR_IPC); | |
37 | } | |
38 | ||
39 | if (pid == 0) { | |
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", | |
46 | strerror(errno)); | |
47 | exit_cleanup(RERR_IPC); | |
48 | } | |
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]); | |
53 | umask(orig_umask); | |
54 | set_blocking(STDIN_FILENO); | |
55 | if (blocking_io) { | |
56 | set_blocking(STDOUT_FILENO); | |
57 | } | |
58 | execvp(command[0], command); | |
59 | rprintf(FERROR, "Failed to exec %s : %s\n", | |
60 | command[0], strerror(errno)); | |
61 | exit_cleanup(RERR_IPC); | |
62 | } | |
63 | ||
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); | |
67 | } | |
68 | ||
69 | *f_in = from_child_pipe[0]; | |
70 | *f_out = to_child_pipe[1]; | |
71 | ||
72 | return pid; | |
73 | } | |
74 | ||
75 | pid_t local_child(int argc, char **argv,int *f_in,int *f_out, | |
76 | int (*child_main)(int, char **)) | |
77 | { | |
78 | pid_t pid; | |
79 | int to_child_pipe[2]; | |
80 | int from_child_pipe[2]; | |
81 | extern int read_batch; /* dw */ | |
82 | ||
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); | |
87 | } | |
88 | ||
89 | ||
90 | pid = do_fork(); | |
91 | if (pid == -1) { | |
92 | rprintf(FERROR,"fork: %s\n",strerror(errno)); | |
93 | exit_cleanup(RERR_IPC); | |
94 | } | |
95 | ||
96 | if (pid == 0) { | |
97 | extern int am_sender; | |
98 | extern int am_server; | |
99 | ||
100 | am_sender = read_batch ? 0 : !am_sender; | |
101 | am_server = 1; | |
102 | ||
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); | |
109 | } | |
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); | |
113 | } | |
114 | ||
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); | |
119 | } | |
120 | ||
121 | *f_in = from_child_pipe[0]; | |
122 | *f_out = to_child_pipe[1]; | |
123 | ||
124 | return pid; | |
125 | } | |
126 | ||
127 |