fix locking of packed ref file in got_ref_open()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
diff --git a/lib/reference.c b/lib/reference.c
index 5c4df8d..3f03033 100644
--- a/lib/reference.c
+++ b/lib/reference.c
@@ -404,6 +404,7 @@ got_ref_open(struct got_reference **ref, struct got_repository *repo,
GOT_REF_HEADS, GOT_REF_TAGS, GOT_REF_REMOTES
};
int i, well_known = is_well_known_ref(refname);
+ struct got_lockfile *lf = NULL;
*ref = NULL;
@@ -435,7 +436,7 @@ got_ref_open(struct got_reference **ref, struct got_repository *repo,
}
if (lock) {
- err = got_lockfile_lock(&(*ref)->lf, packed_refs_path);
+ err = got_lockfile_lock(&lf, packed_refs_path);
if (err)
goto done;
}
@@ -444,15 +445,21 @@ got_ref_open(struct got_reference **ref, struct got_repository *repo,
if (f != NULL) {
err = open_packed_ref(ref, f, subdirs, nitems(subdirs),
refname);
- if (fclose(f) != 0 && err == NULL)
- err = got_error_prefix_errno("fclose");
- if (err || *ref)
- goto done;
+ if (!err) {
+ if (fclose(f) != 0) {
+ err = got_error_prefix_errno("fclose");
+ got_ref_close(*ref);
+ *ref = NULL;
+ } else
+ (*ref)->lf = lf;
+ }
}
}
done:
if (!err && *ref == NULL)
err = got_error_not_ref(refname);
+ if (err && lf)
+ got_lockfile_unlock(lf);
free(path_refs);
return err;
}