@matheusbsbs / matheus-bagliano / commits / acaaca7d70
Fork 0

upload-pack: refactor reading of pack-objects out

Subsequent patches will change how the output of pack-objects is processed, so extract that processing into its own function. Currently, at most 1 character can be buffered (in the "buffered" local variable). One of those patches will require a larger buffer, so replace that "buffered" local variable with a buffer array. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Jun 10, 2020 at 13:57 UTC acaaca7d7030bb349441da10bf9ca6917f30cbb2
1 file changed +49 -35
upload-pack.c
+49 -35
@@ -173,13 +173,52 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
173 return 0;
174 }
175
176 +struct output_state {
177 + char buffer[8193];
178 + int used;
179 +};
180 +
181 +static int relay_pack_data(int pack_objects_out, struct output_state *os,
182 + int use_sideband)
183 +{
184 + /*
185 + * We keep the last byte to ourselves
186 + * in case we detect broken rev-list, so that we
187 + * can leave the stream corrupted. This is
188 + * unfortunate -- unpack-objects would happily
189 + * accept a valid packdata with trailing garbage,
190 + * so appending garbage after we pass all the
191 + * pack data is not good enough to signal
192 + * breakage to downstream.
193 + */
194 + ssize_t readsz;
195 +
196 + readsz = xread(pack_objects_out, os->buffer + os->used,
197 + sizeof(os->buffer) - os->used);
198 + if (readsz < 0) {
199 + return readsz;
200 + }
201 + os->used += readsz;
202 +
203 + if (os->used > 1) {
204 + send_client_data(1, os->buffer, os->used - 1, use_sideband);
205 + os->buffer[0] = os->buffer[os->used - 1];
206 + os->used = 1;
207 + } else {
208 + send_client_data(1, os->buffer, os->used, use_sideband);
209 + os->used = 0;
210 + }
211 +
212 + return readsz;
213 +}
214 +
215 static void create_pack_file(struct upload_pack_data *pack_data)
216 {
217 struct child_process pack_objects = CHILD_PROCESS_INIT;
179 - char data[8193], progress[128];
218 + struct output_state output_state = { { 0 } };
219 + char progress[128];
220 char abort_msg[] = "aborting due to possible repository "
221 "corruption on the remote side.";
182 - int buffered = -1;
222 ssize_t sz;
223 int i;
224 FILE *pipe_fd;
@@ -312,40 +351,16 @@ static void create_pack_file(struct upload_pack_data *pack_data)
351 continue;
352 }
353 if (0 <= pu && (pfd[pu].revents & (POLLIN|POLLHUP))) {
315 - /* Data ready; we keep the last byte to ourselves
316 - * in case we detect broken rev-list, so that we
317 - * can leave the stream corrupted. This is
318 - * unfortunate -- unpack-objects would happily
319 - * accept a valid packdata with trailing garbage,
320 - * so appending garbage after we pass all the
321 - * pack data is not good enough to signal
322 - * breakage to downstream.
323 - */
324 - char *cp = data;
325 - ssize_t outsz = 0;
326 - if (0 <= buffered) {
327 - *cp++ = buffered;
328 - outsz++;
329 - }
330 - sz = xread(pack_objects.out, cp,
331 - sizeof(data) - outsz);
332 - if (0 < sz)
333 - ;
334 - else if (sz == 0) {
354 + int result = relay_pack_data(pack_objects.out,
355 + &output_state,
356 + pack_data->use_sideband);
357 +
358 + if (result == 0) {
359 close(pack_objects.out);
360 pack_objects.out = -1;
337 - }
338 - else
361 + } else if (result < 0) {
362 goto fail;
340 - sz += outsz;
341 - if (1 < sz) {
342 - buffered = data[sz-1] & 0xFF;
343 - sz--;
363 }
345 - else
346 - buffered = -1;
347 - send_client_data(1, data, sz,
348 - pack_data->use_sideband);
364 }
365
366 /*
@@ -370,9 +385,8 @@ static void create_pack_file(struct upload_pack_data *pack_data)
385 }
386
387 /* flush the data */
373 - if (0 <= buffered) {
374 - data[0] = buffered;
375 - send_client_data(1, data, 1,
388 + if (output_state.used > 0) {
389 + send_client_data(1, output_state.buffer, output_state.used,
390 pack_data->use_sideband);
391 fprintf(stderr, "flushed.\n");
392 }