~ubuntu-branches/debian/squeeze/rdup/squeeze

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
}