summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/git2/pkt.h1
-rw-r--r--include/git2/types.h2
-rw-r--r--src/transport.c18
-rw-r--r--src/transport.h6
-rw-r--r--src/transport_git.c74
-rw-r--r--src/transport_local.c53
6 files changed, 75 insertions, 79 deletions
diff --git a/include/git2/pkt.h b/include/git2/pkt.h
index 59826da8a..0b17b3eed 100644
--- a/include/git2/pkt.h
+++ b/include/git2/pkt.h
@@ -52,4 +52,5 @@ struct git_pkt_ref {
};
int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len);
+int git_pkt_send_flush(int s);
void git_pkt_free(git_pkt *pkt);
diff --git a/include/git2/types.h b/include/git2/types.h
index ef80435c4..dae96cf22 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -177,7 +177,7 @@ typedef struct git_transport git_transport;
/** Whether to push or pull */
typedef enum git_net_direction git_net_direction;
-typedef int (*git_transport_cb)(git_transport *transport);
+typedef int (*git_transport_cb)(git_transport **transport);
typedef struct git_remote_head git_remote_head;
typedef struct git_headarray git_headarray;
diff --git a/src/transport.c b/src/transport.c
index fb0dc32c9..59aecb4cf 100644
--- a/src/transport.c
+++ b/src/transport.c
@@ -17,7 +17,7 @@ struct {
{NULL, 0}
};
-static git_transport_cb transport_fill_fn(const char *url)
+static git_transport_cb transport_new_fn(const char *url)
{
int i = 0;
@@ -43,7 +43,7 @@ static git_transport_cb transport_fill_fn(const char *url)
* Public API *
**************/
-int git_transport_dummy(git_transport *GIT_UNUSED(transport))
+int git_transport_dummy(git_transport **GIT_UNUSED(transport))
{
GIT_UNUSED_ARG(transport);
return git__throw(GIT_ENOTIMPLEMENTED, "This protocol isn't implemented. Sorry");
@@ -55,13 +55,11 @@ int git_transport_new(git_transport **out, git_repository *repo, const char *url
git_transport *transport;
int error;
- fn = transport_fill_fn(url);
+ fn = transport_new_fn(url);
- transport = git__malloc(sizeof(git_transport));
- if (transport == NULL)
- return GIT_ENOMEM;
-
- memset(transport, 0x0, sizeof(git_transport));
+ error = fn(&transport);
+ if (error < GIT_SUCCESS)
+ return git__rethrow(error, "Failed to create new transport");
transport->url = git__strdup(url);
if (transport->url == NULL)
@@ -69,10 +67,6 @@ int git_transport_new(git_transport **out, git_repository *repo, const char *url
transport->repo = repo;
- error = fn(transport);
- if (error < GIT_SUCCESS)
- return git__rethrow(error, "Failed to create new transport");
-
*out = transport;
return GIT_SUCCESS;
diff --git a/src/transport.h b/src/transport.h
index e951d4c6b..6d5f037b8 100644
--- a/src/transport.h
+++ b/src/transport.h
@@ -78,8 +78,8 @@ struct git_transport {
void (*free)(struct git_transport *transport);
};
-int git_transport_local(struct git_transport *transport);
-int git_transport_git(struct git_transport *transport);
-int git_transport_dummy(struct git_transport *transport);
+int git_transport_local(struct git_transport **transport);
+int git_transport_git(struct git_transport **transport);
+int git_transport_dummy(struct git_transport **transport);
#endif
diff --git a/src/transport_git.c b/src/transport_git.c
index eb5f70870..ca1f044e3 100644
--- a/src/transport_git.c
+++ b/src/transport_git.c
@@ -45,10 +45,12 @@
#include "netops.h"
typedef struct {
+ git_transport parent;
int socket;
git_vector refs;
git_remote_head **heads;
-} git_priv;
+} transport_git;
+
/*
* Create a git procol request.
*
@@ -141,7 +143,7 @@ static int extract_host_and_port(char **host, char **port, const char *url)
* out. For convenience this also takes care of asking for the remote
* refs
*/
-static int do_connect(git_priv *priv, const char *url)
+static int do_connect(transport_git *t, const char *url)
{
int s = -1;
char *host, *port;
@@ -155,7 +157,7 @@ static int do_connect(git_priv *priv, const char *url)
s = gitno_connect(host, port);
connected = 1;
error = send_request(s, NULL, url);
- priv->socket = s;
+ t->socket = s;
free(host);
free(port);
@@ -171,10 +173,10 @@ static int do_connect(git_priv *priv, const char *url)
/*
* Read from the socket and store the references in the vector
*/
-static int store_refs(git_priv *priv)
+static int store_refs(transport_git *t)
{
- int s = priv->socket;
- git_vector *refs = &priv->refs;
+ int s = t->socket;
+ git_vector *refs = &t->refs;
int error = GIT_SUCCESS;
char buffer[1024];
const char *line_end, *ptr;
@@ -239,33 +241,26 @@ static int store_refs(git_priv *priv)
*/
static int git_connect(git_transport *transport, git_net_direction direction)
{
- git_priv *priv;
+ transport_git *t = (transport_git *) transport;
int error = GIT_SUCCESS;
if (direction == INTENT_PUSH)
return git__throw(GIT_EINVALIDARGS, "Pushing is not supported with the git protocol");
- priv = git__malloc(sizeof(git_priv));
- if (priv == NULL)
- return GIT_ENOMEM;
-
- memset(priv, 0x0, sizeof(git_priv));
- transport->private = priv;
- error = git_vector_init(&priv->refs, 16, NULL);
+ error = git_vector_init(&t->refs, 16, NULL);
if (error < GIT_SUCCESS)
goto cleanup;
/* Connect and ask for the refs */
- error = do_connect(priv, transport->url);
+ error = do_connect(t, transport->url);
if (error < GIT_SUCCESS)
return error;
- error = store_refs(priv);
+ error = store_refs(t);
cleanup:
if (error < GIT_SUCCESS) {
- git_vector_free(&priv->refs);
- free(priv);
+ git_vector_free(&t->refs);
}
return error;
@@ -273,8 +268,8 @@ cleanup:
static int git_ls(git_transport *transport, git_headarray *array)
{
- git_priv *priv = transport->private;
- git_vector *refs = &priv->refs;
+ transport_git *t = (transport_git *) transport;
+ git_vector *refs = &t->refs;
int len = 0;
unsigned int i;
@@ -291,19 +286,19 @@ static int git_ls(git_transport *transport, git_headarray *array)
array->heads[i] = &(((git_pkt_ref *) p)->head);
}
array->len = len;
- priv->heads = array->heads;
+ t->heads = array->heads;
return GIT_SUCCESS;
}
static int git_close(git_transport *transport)
{
- git_priv *priv = transport->private;
- int s = priv->socket;
+ transport_git *t = (transport_git*) transport;
+ int s = t->socket;
int error;
- /* FIXME: We probably want to send a flush pkt back */
-
+ /* Can't do anything if there's an error, so don't bother checking */
+ git_pkt_send_flush(s);
error = close(s);
if (error < 0)
error = git__throw(GIT_EOSERR, "Failed to close socket");
@@ -313,8 +308,8 @@ static int git_close(git_transport *transport)
static void git_free(git_transport *transport)
{
- git_priv *priv = transport->private;
- git_vector *refs = &priv->refs;
+ transport_git *t = (transport_git *) transport;
+ git_vector *refs = &t->refs;
unsigned int i;
for (i = 0; i < refs->length; ++i) {
@@ -323,18 +318,25 @@ static void git_free(git_transport *transport)
}
git_vector_free(refs);
- free(priv->heads);
- free(priv);
- free(transport->url);
- free(transport);
+ free(t->heads);
+ free(t->parent.url);
+ free(t);
}
-int git_transport_git(git_transport *transport)
+int git_transport_git(git_transport **out)
{
- transport->connect = git_connect;
- transport->ls = git_ls;
- transport->close = git_close;
- transport->free = git_free;
+ transport_git *t;
+
+ t = git__malloc(sizeof(transport_git));
+ if (t == NULL)
+ return GIT_ENOMEM;
+
+ t->parent.connect = git_connect;
+ t->parent.ls = git_ls;
+ t->parent.close = git_close;
+ t->parent.free = git_free;
+
+ *out = (git_transport *) t;
return GIT_SUCCESS;
}
diff --git a/src/transport_local.c b/src/transport_local.c
index a096e48c3..5dc5c26ca 100644
--- a/src/transport_local.c
+++ b/src/transport_local.c
@@ -9,9 +9,10 @@
#include "transport.h"
typedef struct {
+ git_transport parent;
git_repository *repo;
git_vector *refs;
-} local_priv;
+} transport_local;
static int cmp_refs(const void *a, const void *b)
{
@@ -29,7 +30,7 @@ static int local_connect(git_transport *transport, git_net_direction GIT_UNUSED(
{
git_repository *repo;
int error;
- local_priv *priv;
+ transport_local *t = (transport_local *) transport;
const char *path;
const char file_prefix[] = "file://";
GIT_UNUSED_ARG(dir);
@@ -44,17 +45,8 @@ static int local_connect(git_transport *transport, git_net_direction GIT_UNUSED(
if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to open remote");
- 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;
+ t->repo = repo;
+ t->parent.connected = 1;
return GIT_SUCCESS;
}
@@ -135,11 +127,11 @@ static int local_ls(git_transport *transport, git_headarray *array)
git_repository *repo;
git_vector *vec;
git_strarray refs;
- local_priv *priv = transport->private;
+ transport_local *t = (transport_local *) transport;
assert(transport && transport->connected);
- repo = priv->repo;
+ repo = t->repo;
error = git_reference_listall(&refs, repo, GIT_REF_LISTALL);
if (error < GIT_SUCCESS)
@@ -172,7 +164,7 @@ static int local_ls(git_transport *transport, git_headarray *array)
array->len = vec->length;
array->heads = (git_remote_head **)vec->contents;
- priv->refs = vec;
+ t->refs = vec;
out:
@@ -191,8 +183,8 @@ 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;
+ transport_local *t = (transport_local *) transport;
+ git_vector *vec = t->refs;
assert(transport);
@@ -203,22 +195,29 @@ static void local_free(git_transport *transport)
}
git_vector_free(vec);
free(vec);
- git_repository_free(priv->repo);
- free(priv);
- free(transport->url);
- free(transport);
+ git_repository_free(t->repo);
+ free(t->parent.url);
+ free(t);
}
/**************
* Public API *
**************/
-int git_transport_local(git_transport *transport)
+int git_transport_local(git_transport **out)
{
- transport->connect = local_connect;
- transport->ls = local_ls;
- transport->close = local_close;
- transport->free = local_free;
+ transport_local *t;
+
+ t = git__malloc(sizeof(transport_local));
+ if (t == NULL)
+ return GIT_ENOMEM;
+
+ t->parent.connect = local_connect;
+ t->parent.ls = local_ls;
+ t->parent.close = local_close;
+ t->parent.free = local_free;
+
+ *out = (git_transport *) t;
return GIT_SUCCESS;
}