1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
1 |
/*
|
2 |
* Copyright (c) 2009 Miek Gieben
|
|
3 |
* child-tr.c handle child stuff
|
|
4 |
*/
|
|
5 |
||
6 |
#include "rdup-tr.h" |
|
7 |
||
8 |
extern sig_atomic_t sig; |
|
9 |
extern gint opt_verbose; |
|
10 |
||
11 |
/* signal.c */
|
|
12 |
void got_sig(int signal); |
|
13 |
||
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
14 |
/* close all pipes except n1 and n2 (-1 is not needed) */
|
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
15 |
void
|
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
16 |
close_pipes(GSList *pipes, int n1, int n2) |
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
17 |
{
|
18 |
GSList *p; |
|
19 |
int *q; |
|
20 |
int j; |
|
21 |
||
22 |
for (j = 0, p = g_slist_nth(pipes, 0); p; p = p->next, j++) { |
|
23 |
q = p->data; |
|
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
24 |
/* msg("Pipe set %d fds %d %d", j, q[0], q[1]); */
|
25 |
if (j == n1 || j == n2) |
|
26 |
continue; |
|
27 |
#if 0
|
|
28 |
if (opt_verbose > 0)
|
|
29 |
msg("Closing pipe set %d", j);
|
|
30 |
#endif
|
|
31 |
close(q[0]); |
|
32 |
close(q[1]); |
|
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
33 |
}
|
34 |
}
|
|
35 |
||
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
36 |
/* return 0 if all ok, -1 for trouble */
|
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
37 |
int
|
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
38 |
wait_pids(GSList *pids, int flags) |
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
39 |
{
|
40 |
GSList *p; |
|
41 |
int status; |
|
42 |
int ret = 0; |
|
43 |
||
44 |
if (!pids) |
|
45 |
return 0; |
|
46 |
||
47 |
for (p = g_slist_nth(pids, 0); p; p = p->next) { |
|
48 |
if (sig != 0) |
|
49 |
signal_abort(sig); |
|
50 |
||
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
51 |
waitpid(*(pid_t* )(p->data), &status, flags); |
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
52 |
if (WIFEXITED(status)) { |
53 |
#if 0
|
|
54 |
msg("Child exit %d\n", WEXITSTATUS(status));
|
|
55 |
#endif
|
|
56 |
if (WEXITSTATUS(status) != 0) |
|
57 |
ret = -1; |
|
58 |
}
|
|
59 |
}
|
|
60 |
return ret; |
|
61 |
}
|
|
62 |
||
63 |
/* create pipes and childs, return pids */
|
|
64 |
GSList * |
|
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
65 |
create_childeren(GSList *child, GSList **pipes, int file) |
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
66 |
{
|
67 |
GSList *p; |
|
68 |
GSList *pids = NULL; |
|
69 |
GSList *cpipe = NULL; |
|
70 |
||
71 |
char **args; |
|
72 |
int *pips; |
|
73 |
int childs, j; |
|
74 |
pid_t *cpid; |
|
75 |
||
76 |
if (!child) |
|
77 |
return NULL; |
|
78 |
||
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
79 |
/* create all pipes before forking
|
80 |
* As a parent we read from the last pipe created
|
|
81 |
* We attach file to the input of the first child
|
|
82 |
* This eliminates to use of a tmp file
|
|
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
83 |
*/
|
84 |
childs = g_slist_length(child); |
|
85 |
for (j = 0; j < childs; j++) { |
|
86 |
pips = g_malloc(2 * sizeof(int)); |
|
87 |
if (pipe(pips) == -1) { |
|
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
88 |
msg(_("Failure creating pipes")); |
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
89 |
exit(EXIT_FAILURE); |
90 |
}
|
|
91 |
cpipe = g_slist_append(cpipe, pips); |
|
92 |
}
|
|
93 |
||
94 |
for (j = 0, p = g_slist_nth(child, 0); p; p = p->next, j++) { |
|
95 |
if (sig != 0) |
|
96 |
signal_abort(sig); |
|
97 |
||
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
98 |
/* fork, exec child */
|
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
99 |
args = (char**) p->data; |
100 |
cpid = g_malloc(sizeof(pid_t)); |
|
101 |
pips = (g_slist_nth(cpipe, j))->data; |
|
102 |
||
103 |
if ( (*cpid = fork()) == -1) { |
|
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
104 |
msg(_("Fork error")); |
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
105 |
exit(EXIT_FAILURE); |
106 |
}
|
|
107 |
||
108 |
if (*cpid != 0) { /* parent */ |
|
109 |
/* save the pids */
|
|
110 |
pids = g_slist_append(pids, cpid); |
|
111 |
} else { /* child */ |
|
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
112 |
if (j == 0) { |
113 |
/* dup f to stdin */
|
|
114 |
if (dup2(file, 0) == -1) |
|
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
115 |
exit(EXIT_FAILURE); |
116 |
close(pips[0]); |
|
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
117 |
/* pips[1] still alive */
|
118 |
if (dup2(pips[1], 1) == -1) |
|
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
119 |
exit(EXIT_FAILURE); |
120 |
||
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
121 |
close_pipes(cpipe, j, -1); |
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
122 |
} else { |
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
123 |
close(file); |
124 |
/* close read end */
|
|
125 |
close(pips[0]); |
|
126 |
/* dup write to stdout */
|
|
127 |
if (dup2(pips[1], 1) == -1) |
|
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
128 |
exit(EXIT_FAILURE); |
129 |
||
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
130 |
/* re-use pips for the previous pipe pair */
|
131 |
pips = (g_slist_nth(cpipe, j - 1))->data; |
|
132 |
/* dup read to stdin */
|
|
133 |
if (dup2(pips[0], 0) == -1) |
|
134 |
exit(EXIT_FAILURE); |
|
135 |
/* and close 1 */
|
|
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
136 |
close(pips[1]); |
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
137 |
|
138 |
close_pipes(cpipe, j, j - 1); |
|
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
139 |
}
|
140 |
||
141 |
/* finally ... exec */
|
|
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
142 |
if ( execvp(args[0], args) == -1) |
143 |
exit(EXIT_FAILURE); |
|
144 |
||
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
145 |
/* never reached */
|
146 |
exit(EXIT_SUCCESS); |
|
147 |
}
|
|
148 |
}
|
|
1.1.5
by Jose Carlos Garcia Sogo
Import upstream version 1.0.5 |
149 |
/* all childeren created, close all pipes except the last one */
|
150 |
close_pipes(cpipe, childs - 1, -1); |
|
151 |
/* close write end, we only need to read as parent */
|
|
152 |
pips = (g_slist_last(cpipe))->data; |
|
153 |
close(pips[1]); |
|
1.1.3
by Jose Carlos Garcia Sogo
Import upstream version 0.6.4 |
154 |
|
155 |
*pipes = cpipe; |
|
156 |
return pids; |
|
157 |
}
|