local transport: keep better track of memory Store the ref information in a private struct so we can free it together with the rest. Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
diff --git a/src/transport_local.c b/src/transport_local.c
index 0e9f71b..a096e48 100644
--- a/src/transport_local.c
+++ b/src/transport_local.c
@@ -8,6 +8,11 @@
#include "refs.h"
#include "transport.h"
+typedef struct {
+ git_repository *repo;
+ git_vector *refs;
+} local_priv;
+
static int cmp_refs(const void *a, const void *b)
{
const char *stra = *(const char **) a;
@@ -24,6 +29,7 @@ static int local_connect(git_transport *transport, git_net_direction GIT_UNUSED(
{
git_repository *repo;
int error;
+ local_priv *priv;
const char *path;
const char file_prefix[] = "file://";
GIT_UNUSED_ARG(dir);
@@ -38,7 +44,15 @@ static int local_connect(git_transport *transport, git_net_direction GIT_UNUSED(
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to open remote");
- transport->private = repo;
+ priv = git__malloc(sizeof(local_priv));
+ if (priv == NULL) {
+ git_repository_free(repo);
+ return GIT_ENOMEM;
+ }
+
+ priv->repo = repo;
+
+ transport->private = priv;
transport->connected = 1;
@@ -119,18 +133,25 @@ static int local_ls(git_transport *transport, git_headarray *array)
int error;
unsigned int i;
git_repository *repo;
- git_vector vec;
+ git_vector *vec;
git_strarray refs;
+ local_priv *priv = transport->private;
assert(transport && transport->connected);
- repo = transport->private;
+ repo = priv->repo;
error = git_reference_listall(&refs, repo, GIT_REF_LISTALL);
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to list remote heads");
- error = git_vector_init(&vec, refs.count, NULL);
+ vec = git__malloc(sizeof(git_vector));
+ if (vec == NULL) {
+ error = GIT_ENOMEM;
+ goto out;
+ }
+
+ error = git_vector_init(vec, refs.count, NULL);
if (error < GIT_SUCCESS)
return error;
@@ -138,23 +159,24 @@ static int local_ls(git_transport *transport, git_headarray *array)
qsort(refs.strings, refs.count, sizeof(char *), cmp_refs);
/* Add HEAD */
- error = add_ref(GIT_HEAD_FILE, repo, &vec);
+ error = add_ref(GIT_HEAD_FILE, repo, vec);
if (error < GIT_SUCCESS)
goto out;
for (i = 0; i < refs.count; ++i) {
- error = add_ref(refs.strings[i], repo, &vec);
+ error = add_ref(refs.strings[i], repo, vec);
if (error < GIT_SUCCESS)
goto out;
}
- array->len = vec.length;
- array->heads = (git_remote_head **) vec.contents;
+ array->len = vec->length;
+ array->heads = (git_remote_head **)vec->contents;
+
+ priv->refs = vec;
out:
- if (error < GIT_SUCCESS) {
- git_strarray_free(&refs);
- }
+
+ git_strarray_free(&refs);
return error;
}
@@ -168,9 +190,21 @@ static int local_close(git_transport *GIT_UNUSED(transport))
static void local_free(git_transport *transport)
{
+ unsigned int i;
+ local_priv *priv = transport->private;
+ git_vector *vec = priv->refs;
+
assert(transport);
- git_repository_free(transport->private);
+ for (i = 0; i < vec->length; ++i) {
+ git_remote_head *h = git_vector_get(vec, i);
+ free(h->name);
+ free(h);
+ }
+ git_vector_free(vec);
+ free(vec);
+ git_repository_free(priv->repo);
+ free(priv);
free(transport->url);
free(transport);
}