bundle: don't leak an fd in case of early return

In successful operation `write_pack_data` will close the `bundle_fd`, but when we exit early, we need to take care of the file descriptor as well as the lock file ourselves. The lock file may be deleted at the end of running the program, but we are in library code, so we should not rely on that. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Stefan Beller committed Mar 31, 2016 at 17:35 UTC f5ff5fb56485979895cff5954e4db1ea4ff4c9f7
1 file changed +17 -6
bundle.c
+17 -6
@@ -435,12 +435,14 @@ int create_bundle(struct bundle_header *header, const char *path,
435
436 /* write prerequisites */
437 if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv))
438 - return -1;
438 + goto err;
439
440 argc = setup_revisions(argc, argv, &revs, NULL);
441
442 - if (argc > 1)
443 - return error(_("unrecognized argument: %s"), argv[1]);
442 + if (argc > 1) {
443 + error(_("unrecognized argument: %s"), argv[1]);
444 + goto err;
445 + }
446
447 object_array_remove_duplicates(&revs.pending);
448
@@ -448,17 +450,26 @@ int create_bundle(struct bundle_header *header, const char *path,
450 if (!ref_count)
451 die(_("Refusing to create empty bundle."));
452 else if (ref_count < 0)
451 - return -1;
453 + goto err;
454
455 /* write pack */
454 - if (write_pack_data(bundle_fd, &revs))
455 - return -1;
456 + if (write_pack_data(bundle_fd, &revs)) {
457 + bundle_fd = -1; /* already closed by the above call */
458 + goto err;
459 + }
460
461 if (!bundle_to_stdout) {
462 if (commit_lock_file(&lock))
463 die_errno(_("cannot create '%s'"), path);
464 }
465 return 0;
466 +err:
467 + if (!bundle_to_stdout) {
468 + if (0 <= bundle_fd)
469 + close(bundle_fd);
470 + rollback_lock_file(&lock);
471 + }
472 + return -1;
473 }
474
475 int unbundle(struct bundle_header *header, int bundle_fd, int flags)