@@ -144,6 +144,7 @@ static void create_pack_file(void)
144144 char abort_msg [] = "aborting due to possible repository "
145145 "corruption on the remote side." ;
146146 int buffered = -1 ;
147+ ssize_t sz ;
147148 const char * argv [10 ];
148149 int arg = 0 ;
149150
@@ -168,22 +169,15 @@ static void create_pack_file(void)
168169 pack_objects .git_cmd = 1 ;
169170 pack_objects .argv = argv ;
170171
171- if (start_command (& pack_objects )) {
172- /* daemon sets things up to ignore TERM */
173- kill (rev_list .pid , SIGKILL );
172+ if (start_command (& pack_objects ))
174173 die ("git-upload-pack: unable to fork git-pack-objects" );
175- }
176174
177175 /* We read from pack_objects.err to capture stderr output for
178176 * progress bar, and pack_objects.out to capture the pack data.
179177 */
180178
181179 while (1 ) {
182- const char * who ;
183180 struct pollfd pfd [2 ];
184- pid_t pid ;
185- int status ;
186- ssize_t sz ;
187181 int pe , pu , pollsize ;
188182
189183 reset_timeout ();
@@ -204,123 +198,91 @@ static void create_pack_file(void)
204198 pollsize ++ ;
205199 }
206200
207- if (pollsize ) {
208- if (poll (pfd , pollsize , -1 ) < 0 ) {
209- if (errno != EINTR ) {
210- error ("poll failed, resuming: %s" ,
211- strerror (errno ));
212- sleep (1 );
213- }
214- continue ;
215- }
216- if (0 <= pu && (pfd [pu ].revents & (POLLIN |POLLHUP ))) {
217- /* Data ready; we keep the last byte
218- * to ourselves in case we detect
219- * broken rev-list, so that we can
220- * leave the stream corrupted. This
221- * is unfortunate -- unpack-objects
222- * would happily accept a valid pack
223- * data with trailing garbage, so
224- * appending garbage after we pass all
225- * the pack data is not good enough to
226- * signal breakage to downstream.
227- */
228- char * cp = data ;
229- ssize_t outsz = 0 ;
230- if (0 <= buffered ) {
231- * cp ++ = buffered ;
232- outsz ++ ;
233- }
234- sz = xread (pack_objects .out , cp ,
235- sizeof (data ) - outsz );
236- if (0 < sz )
237- ;
238- else if (sz == 0 ) {
239- close (pack_objects .out );
240- pack_objects .out = -1 ;
241- }
242- else
243- goto fail ;
244- sz += outsz ;
245- if (1 < sz ) {
246- buffered = data [sz - 1 ] & 0xFF ;
247- sz -- ;
248- }
249- else
250- buffered = -1 ;
251- sz = send_client_data (1 , data , sz );
252- if (sz < 0 )
253- goto fail ;
254- }
255- if (0 <= pe && (pfd [pe ].revents & (POLLIN |POLLHUP ))) {
256- /* Status ready; we ship that in the side-band
257- * or dump to the standard error.
258- */
259- sz = xread (pack_objects .err , progress ,
260- sizeof (progress ));
261- if (0 < sz )
262- send_client_data (2 , progress , sz );
263- else if (sz == 0 ) {
264- close (pack_objects .err );
265- pack_objects .err = -1 ;
266- }
267- else
268- goto fail ;
201+ if (!pollsize )
202+ break ;
203+
204+ if (poll (pfd , pollsize , -1 ) < 0 ) {
205+ if (errno != EINTR ) {
206+ error ("poll failed, resuming: %s" ,
207+ strerror (errno ));
208+ sleep (1 );
269209 }
210+ continue ;
270211 }
271-
272- /* See if the children are still there */
273- if (rev_list .pid || pack_objects .pid ) {
274- pid = waitpid (-1 , & status , WNOHANG );
275- if (!pid )
276- continue ;
277- who = ((pid == rev_list .pid ) ? "git-rev-list" :
278- (pid == pack_objects .pid ) ? "git-pack-objects" :
279- NULL );
280- if (!who ) {
281- if (pid < 0 ) {
282- error ("git-upload-pack: %s" ,
283- strerror (errno ));
284- goto fail ;
285- }
286- error ("git-upload-pack: we weren't "
287- "waiting for %d" , pid );
288- continue ;
212+ if (0 <= pu && (pfd [pu ].revents & (POLLIN |POLLHUP ))) {
213+ /* Data ready; we keep the last byte to ourselves
214+ * in case we detect broken rev-list, so that we
215+ * can leave the stream corrupted. This is
216+ * unfortunate -- unpack-objects would happily
217+ * accept a valid packdata with trailing garbage,
218+ * so appending garbage after we pass all the
219+ * pack data is not good enough to signal
220+ * breakage to downstream.
221+ */
222+ char * cp = data ;
223+ ssize_t outsz = 0 ;
224+ if (0 <= buffered ) {
225+ * cp ++ = buffered ;
226+ outsz ++ ;
227+ }
228+ sz = xread (pack_objects .out , cp ,
229+ sizeof (data ) - outsz );
230+ if (0 < sz )
231+ ;
232+ else if (sz == 0 ) {
233+ close (pack_objects .out );
234+ pack_objects .out = -1 ;
289235 }
290- if (!WIFEXITED (status ) || WEXITSTATUS (status ) > 0 ) {
291- error ("git-upload-pack: %s died with error." ,
292- who );
236+ else
293237 goto fail ;
238+ sz += outsz ;
239+ if (1 < sz ) {
240+ buffered = data [sz - 1 ] & 0xFF ;
241+ sz -- ;
294242 }
295- if (pid == rev_list .pid )
296- rev_list .pid = 0 ;
297- if (pid == pack_objects .pid )
298- pack_objects .pid = 0 ;
299- if (rev_list .pid || pack_objects .pid )
300- continue ;
301- }
302-
303- /* both died happily */
304- if (pollsize )
305- continue ;
306-
307- /* flush the data */
308- if (0 <= buffered ) {
309- data [0 ] = buffered ;
310- sz = send_client_data (1 , data , 1 );
243+ else
244+ buffered = -1 ;
245+ sz = send_client_data (1 , data , sz );
311246 if (sz < 0 )
312247 goto fail ;
313- fprintf (stderr , "flushed.\n" );
314248 }
315- if (use_sideband )
316- packet_flush (1 );
317- return ;
249+ if (0 <= pe && (pfd [pe ].revents & (POLLIN |POLLHUP ))) {
250+ /* Status ready; we ship that in the side-band
251+ * or dump to the standard error.
252+ */
253+ sz = xread (pack_objects .err , progress ,
254+ sizeof (progress ));
255+ if (0 < sz )
256+ send_client_data (2 , progress , sz );
257+ else if (sz == 0 ) {
258+ close (pack_objects .err );
259+ pack_objects .err = -1 ;
260+ }
261+ else
262+ goto fail ;
263+ }
264+ }
265+
266+ if (finish_command (& pack_objects )) {
267+ error ("git-upload-pack: git-pack-objects died with error." );
268+ goto fail ;
269+ }
270+ if (finish_async (& rev_list ))
271+ goto fail ; /* error was already reported */
272+
273+ /* flush the data */
274+ if (0 <= buffered ) {
275+ data [0 ] = buffered ;
276+ sz = send_client_data (1 , data , 1 );
277+ if (sz < 0 )
278+ goto fail ;
279+ fprintf (stderr , "flushed.\n" );
318280 }
281+ if (use_sideband )
282+ packet_flush (1 );
283+ return ;
284+
319285 fail :
320- if (pack_objects .pid )
321- kill (pack_objects .pid , SIGKILL );
322- if (rev_list .pid )
323- kill (rev_list .pid , SIGKILL );
324286 send_client_data (3 , abort_msg , sizeof (abort_msg ));
325287 die ("git-upload-pack: %s" , abort_msg );
326288}
0 commit comments