19 if (a > b) |
19 if (a > b) |
20 return a; |
20 return a; |
21 return b; |
21 return b; |
22 } |
22 } |
23 |
23 |
24 static int fork_app(int *opipe, char * const command[]) |
24 static int fork_app(int *opipe /*[3]*/, char * const command[]) |
25 { |
25 { |
26 int p_input[2]; /* from mpg321 to us */ |
26 int p_input[2]; /* from mpg321 to us */ |
27 int p_output[2]; /* from us to mpg321 */ |
27 int p_output[2]; /* from us to mpg321 */ |
|
28 int p_error[2]; /* from mpg321 to us, its stderr */ |
28 int pid; |
29 int pid; |
29 int res; |
30 int res; |
30 |
31 |
31 pipe(p_input); |
32 pipe(p_input); |
32 pipe(p_output); |
33 pipe(p_output); |
|
34 pipe(p_error); |
33 opipe[0] = p_input[0]; /* For us to read */ |
35 opipe[0] = p_input[0]; /* For us to read */ |
34 opipe[1] = p_output[1]; /* For us to write */ |
36 opipe[1] = p_output[1]; /* For us to write */ |
|
37 opipe[2] = p_error[0]; /* For us to read */ |
35 |
38 |
36 pid = fork(); |
39 pid = fork(); |
37 |
40 |
38 switch(pid) |
41 switch(pid) |
39 { |
42 { |
40 case 0: /* child */ |
43 case 0: /* child */ |
41 close(p_input[0]); |
44 close(p_input[0]); |
42 res = dup2(p_input[1], 1); |
45 res = dup2(p_input[1], 1); |
43 if (res == -1) perror("Dup2 1"); |
46 if (res == -1) perror("Dup2 1"); |
44 res = dup2(p_input[1], 2); |
47 close(p_error[0]); |
|
48 res = dup2(p_error[1], 2); |
45 if (res == -1) perror("Dup2 2"); |
49 if (res == -1) perror("Dup2 2"); |
46 close(p_input[1]); |
50 close(p_input[1]); |
|
51 close(p_error[1]); |
|
52 |
47 close(p_output[1]); |
53 close(p_output[1]); |
48 res = dup2(p_output[0], 0); |
54 res = dup2(p_output[0], 0); |
49 if (res == -1) perror("Dup2 3"); |
55 if (res == -1) perror("Dup2 3"); |
50 close(p_output[0]); |
56 close(p_output[0]); |
51 |
57 |
76 |
83 |
77 static void loop(const int *child_pipe, int lsocket) |
84 static void loop(const int *child_pipe, int lsocket) |
78 { |
85 { |
79 char buf[100]; |
86 char buf[100]; |
80 fd_set read_set; |
87 fd_set read_set; |
81 int child_read, child_write; |
88 int child_read, child_write, child_read_error; |
82 int maxfd; |
89 int maxfd; |
83 int opened_socket; |
90 int opened_socket; |
84 int stdin_opened; |
91 int stdin_opened; |
|
92 int child_read_opened, child_read_error_opened; |
85 int res; |
93 int res; |
86 |
94 |
87 child_read = child_pipe[0]; |
95 child_read = child_pipe[0]; |
|
96 child_read_error = child_pipe[2]; |
88 child_write = child_pipe[1]; |
97 child_write = child_pipe[1]; |
89 |
98 |
90 stdin_opened = 1; |
99 stdin_opened = 1; |
91 opened_socket = -1; /* no socket opened */ |
100 opened_socket = -1; /* no socket opened */ |
|
101 child_read_opened = 1; |
|
102 child_read_error_opened = 1; |
92 do |
103 do |
93 { |
104 { |
94 FD_ZERO(&read_set); |
105 FD_ZERO(&read_set); |
|
106 maxfd = 0; |
95 |
107 |
96 if (stdin_opened) |
108 if (stdin_opened) |
97 FD_SET(0, &read_set); |
109 FD_SET(0, &read_set); |
98 FD_SET(child_read, &read_set); |
110 |
99 maxfd = child_read; |
111 if (child_read_opened) |
|
112 { |
|
113 FD_SET(child_read, &read_set); |
|
114 maxfd = max(maxfd, child_read); |
|
115 } |
|
116 |
|
117 if (child_read_error_opened) |
|
118 { |
|
119 FD_SET(child_read_error, &read_set); |
|
120 maxfd = max(maxfd, child_read_error); |
|
121 } |
|
122 |
100 if (opened_socket >= 0) |
123 if (opened_socket >= 0) |
101 { |
124 { |
102 FD_SET(opened_socket, &read_set); |
125 FD_SET(opened_socket, &read_set); |
103 maxfd = max(maxfd, opened_socket); |
126 maxfd = max(maxfd, opened_socket); |
104 } |
127 } |
118 continue; |
141 continue; |
119 else |
142 else |
120 error("Error in select()"); |
143 error("Error in select()"); |
121 } |
144 } |
122 |
145 |
123 if (FD_ISSET(child_read, &read_set)) |
146 if (child_read_opened && FD_ISSET(child_read, &read_set)) |
124 { |
147 { |
125 res = forward_app_data(child_read, 1); |
148 res = forward_app_data(child_read, 1); |
126 if (res == 0) |
149 if (res == 0) |
127 break; |
150 { |
|
151 close(1); |
|
152 child_read_opened = 0; |
|
153 if (child_read_error_opened == 0) |
|
154 break; |
|
155 } |
|
156 } |
|
157 if (child_read_error_opened && FD_ISSET(child_read_error, &read_set)) |
|
158 { |
|
159 res = forward_app_data(child_read_error, 2); |
|
160 if (res == 0) |
|
161 { |
|
162 close(2); |
|
163 child_read_error_opened = 0; |
|
164 if (child_read_opened == 0) |
|
165 break; |
|
166 } |
128 } |
167 } |
129 if (FD_ISSET(0, &read_set)) |
168 if (FD_ISSET(0, &read_set)) |
130 { |
169 { |
131 res = forward_app_data(0, child_write); |
170 res = forward_app_data(0, child_write); |
132 if (res == 0) |
171 if (res == 0) |