@@ -102,14 +102,52 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
102102 return 0 ;
103103}
104104
105+ struct output_state {
106+ char buffer [8193 ];
107+ int used ;
108+ };
109+
110+ static int relay_pack_data (int pack_objects_out , struct output_state * os )
111+ {
112+ /*
113+ * We keep the last byte to ourselves
114+ * in case we detect broken rev-list, so that we
115+ * can leave the stream corrupted. This is
116+ * unfortunate -- unpack-objects would happily
117+ * accept a valid packdata with trailing garbage,
118+ * so appending garbage after we pass all the
119+ * pack data is not good enough to signal
120+ * breakage to downstream.
121+ */
122+ ssize_t readsz ;
123+
124+ readsz = xread (pack_objects_out , os -> buffer + os -> used ,
125+ sizeof (os -> buffer ) - os -> used );
126+ if (readsz < 0 ) {
127+ return readsz ;
128+ }
129+ os -> used += readsz ;
130+
131+ if (os -> used > 1 ) {
132+ send_client_data (1 , os -> buffer , os -> used - 1 );
133+ os -> buffer [0 ] = os -> buffer [os -> used - 1 ];
134+ os -> used = 1 ;
135+ } else {
136+ send_client_data (1 , os -> buffer , os -> used );
137+ os -> used = 0 ;
138+ }
139+
140+ return readsz ;
141+ }
142+
105143static void create_pack_file (const struct object_array * have_obj ,
106144 const struct object_array * want_obj )
107145{
108146 struct child_process pack_objects = CHILD_PROCESS_INIT ;
109- char data [8193 ], progress [128 ];
147+ struct output_state output_state = {0 };
148+ char progress [128 ];
110149 char abort_msg [] = "aborting due to possible repository "
111150 "corruption on the remote side." ;
112- int buffered = -1 ;
113151 ssize_t sz ;
114152 int i ;
115153 FILE * pipe_fd ;
@@ -239,39 +277,15 @@ static void create_pack_file(const struct object_array *have_obj,
239277 continue ;
240278 }
241279 if (0 <= pu && (pfd [pu ].revents & (POLLIN |POLLHUP ))) {
242- /* Data ready; we keep the last byte to ourselves
243- * in case we detect broken rev-list, so that we
244- * can leave the stream corrupted. This is
245- * unfortunate -- unpack-objects would happily
246- * accept a valid packdata with trailing garbage,
247- * so appending garbage after we pass all the
248- * pack data is not good enough to signal
249- * breakage to downstream.
250- */
251- char * cp = data ;
252- ssize_t outsz = 0 ;
253- if (0 <= buffered ) {
254- * cp ++ = buffered ;
255- outsz ++ ;
256- }
257- sz = xread (pack_objects .out , cp ,
258- sizeof (data ) - outsz );
259- if (0 < sz )
260- ;
261- else if (sz == 0 ) {
280+ int result = relay_pack_data (pack_objects .out ,
281+ & output_state );
282+
283+ if (result == 0 ) {
262284 close (pack_objects .out );
263285 pack_objects .out = -1 ;
264- }
265- else
286+ } else if (result < 0 ) {
266287 goto fail ;
267- sz += outsz ;
268- if (1 < sz ) {
269- buffered = data [sz - 1 ] & 0xFF ;
270- sz -- ;
271288 }
272- else
273- buffered = -1 ;
274- send_client_data (1 , data , sz );
275289 }
276290
277291 /*
@@ -296,9 +310,8 @@ static void create_pack_file(const struct object_array *have_obj,
296310 }
297311
298312 /* flush the data */
299- if (0 <= buffered ) {
300- data [0 ] = buffered ;
301- send_client_data (1 , data , 1 );
313+ if (output_state .used > 0 ) {
314+ send_client_data (1 , output_state .buffer , output_state .used );
302315 fprintf (stderr , "flushed.\n" );
303316 }
304317 if (use_sideband )
0 commit comments