Show changes to transport-helper.c +72 −38
diff --git a/transport-helper.c b/transport-helper.c
index 0e4da79..697f026 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -8,6 +8,8 @@
#include "quote.h"
#include "remote.h"
+static int debug = 0;
+
struct helper_data
{
const char *name;
@@ -25,6 +27,47 @@ struct helper_data
struct git_transport_options gitoptions;
};
+static void sendline(struct helper_data *helper, struct strbuf *buffer)
+{
+ if(debug)
+ fprintf(stderr, "Debug: Remote helper: -> %s", buffer->buf);
+ if(write_in_full(helper->helper->in, buffer->buf, buffer->len)
+ != buffer->len) {
+ die_errno("Full write to remote helper failed");
+ }
+}
+
+static int recvline(struct helper_data *helper, struct strbuf *buffer,
+ int supress_finish)
+{
+ strbuf_reset(buffer);
+ if (strbuf_getline(buffer, helper->out, '\n') == EOF) {
+ if(debug)
+ fprintf(stderr, "Debug: Remote helper quit.\n");
+ if(!supress_finish)
+ finish_command(helper->helper);
+ exit(128);
+ }
+
+ if(debug)
+ fprintf(stderr, "Debug: Remote helper: <- %s\n", buffer->buf);
+ return 0;
+}
+
+static void xchgline(struct helper_data *helper, struct strbuf *buffer)
+{
+ sendline(helper, buffer);
+ recvline(helper, buffer, 1);
+}
+
+static void write_constant(int fd, const char *str)
+{
+ if(debug)
+ fprintf(stderr, "Debug: Remote helper: -> %s", str);
+ if(write_in_full(fd, str, strlen(str)) != strlen(str))
+ die_errno("Full write to remote helper failed");
+}
+
static struct child_process* helper_disown(struct transport *transport)
{
struct helper_data *data = transport->data;
@@ -99,23 +142,15 @@ static struct child_process *get_helper(struct transport *transport)
data->out = xfdopen(duped, "r");
setvbuf(data->out, NULL, _IONBF, 0);
- write_str_in_full(helper->in, "capabilities\n");
+ write_constant(helper->in, "capabilities\n");
while (1) {
- if (strbuf_getline(&buf, data->out, '\n') == EOF) {
- /* If we haven't seen line yet, try to finish the
- command so we get error message about failed
- execution. */
- if(!seen_line)
- finish_command(helper);
-
- exit(128); /* child died, message supplied already */
- }
-
+ recvline(data, &buf, seen_line);
seen_line = 1;
if (!*buf.buf)
break;
+ if(debug) fprintf(stderr, "Debug: Got cap %s\n", buf.buf);
if (!strcmp(buf.buf, "fetch"))
data->fetch = 1;
if (!strcmp(buf.buf, "option"))
@@ -145,14 +180,19 @@ static struct child_process *get_helper(struct transport *transport)
free(refspecs);
}
strbuf_release(&buf);
+ if(debug) fprintf(stderr, "Debug: Capabilities complete.\n");
return data->helper;
}
static int disconnect_helper(struct transport *transport)
{
struct helper_data *data = transport->data;
+ struct strbuf buf = STRBUF_INIT;
+
if (data->helper) {
- write_str_in_full(data->helper->in, "\n");
+ if(debug) fprintf(stderr, "Debug: Disconnecting.\n");
+ strbuf_addf(&buf, "\n");
+ sendline(data, &buf);
close(data->helper->in);
close(data->helper->out);
fclose(data->out);
@@ -182,10 +222,11 @@ static int set_helper_option(struct transport *transport,
const char *name, const char *value)
{
struct helper_data *data = transport->data;
- struct child_process *helper = get_helper(transport);
struct strbuf buf = STRBUF_INIT;
int i, ret, is_bool = 0;
+ get_helper(transport);
+
if (!data->option)
return 1;
@@ -208,12 +249,7 @@ static int set_helper_option(struct transport *transport,
quote_c_style(value, &buf, NULL, 0);
strbuf_addch(&buf, '\n');
- if (write_in_full(helper->in, buf.buf, buf.len) != buf.len)
- die_errno("cannot send option to %s", data->name);
-
- strbuf_reset(&buf);
- if (strbuf_getline(&buf, data->out, '\n') == EOF)
- exit(128); /* child died, message supplied already */
+ xchgline(data, &buf);
if (!strcmp(buf.buf, "ok"))
ret = 0;
@@ -273,13 +309,10 @@ static int fetch_with_fetch(struct transport *transport,
}
strbuf_addch(&buf, '\n');
- if (write_in_full(data->helper->in, buf.buf, buf.len) != buf.len)
- die_errno("cannot send fetch to %s", data->name);
+ sendline(data, &buf);
while (1) {
- strbuf_reset(&buf);
- if (strbuf_getline(&buf, data->out, '\n') == EOF)
- exit(128); /* child died, message supplied already */
+ recvline(data, &buf, 1);
if (!prefixcmp(buf.buf, "lock ")) {
const char *name = buf.buf + 5;
@@ -314,12 +347,13 @@ static int fetch_with_import(struct transport *transport,
int nr_heads, struct ref **to_fetch)
{
struct child_process fastimport;
- struct child_process *helper = get_helper(transport);
struct helper_data *data = transport->data;
int i;
struct ref *posn;
struct strbuf buf = STRBUF_INIT;
+ get_helper(transport);
+
if (get_importer(transport, &fastimport))
die("Couldn't run fast-import");
@@ -329,7 +363,7 @@ static int fetch_with_import(struct transport *transport,
continue;
strbuf_addf(&buf, "import %s\n", posn->name);
- write_in_full(helper->in, buf.buf, buf.len);
+ sendline(data, &buf);
strbuf_reset(&buf);
}
disconnect_helper(transport);
@@ -370,12 +404,12 @@ static int _process_connect_or_invoke(struct transport *transport,
} else
return 0;
- write_in_full(helper->in, cmdbuf.buf, cmdbuf.len);
- strbuf_reset(&cmdbuf);
- if (strbuf_getline(&cmdbuf, data->out, '\n') == EOF)
- exit(128); /* child died, message supplied already */
- if(!strcmp(cmdbuf.buf, "OK"))
+ xchgline(data, &cmdbuf);
+ if(!strcmp(cmdbuf.buf, "OK")) {
+ if(debug) fprintf(stderr, "Debug: Layer 6 link ready, "
+ "starting layer 7...\n");
return 1;
+ }
else if(!strcmp(cmdbuf.buf, "FALLBACK"))
return 0;
else if(!strcmp(cmdbuf.buf, "ERROR"))
@@ -508,17 +542,14 @@ static int push_refs(struct transport *transport,
}
strbuf_addch(&buf, '\n');
- if (write_in_full(helper->in, buf.buf, buf.len) != buf.len)
- exit(128);
+ sendline(data, &buf);
ref = remote_refs;
while (1) {
char *refname, *msg;
int status;
- strbuf_reset(&buf);
- if (strbuf_getline(&buf, data->out, '\n') == EOF)
- exit(128); /* child died, message supplied already */
+ recvline(data, &buf, 1);
if (!buf.len)
break;
@@ -608,8 +639,7 @@ static struct ref *get_refs_list(struct transport *transport, int for_push)
while (1) {
char *eov, *eon;
- if (strbuf_getline(&buf, data->out, '\n') == EOF)
- exit(128); /* child died, message supplied already */
+ recvline(data, &buf, 1);
if (!*buf.buf)
break;
@@ -634,6 +664,7 @@ static struct ref *get_refs_list(struct transport *transport, int for_push)
}
tail = &((*tail)->next);
}
+ if(debug) fprintf(stderr, "Debug: Read ref listing.\n");
strbuf_release(&buf);
for (posn = ret; posn; posn = posn->next)
@@ -647,6 +678,9 @@ int transport_helper_init(struct transport *transport, const char *name)
struct helper_data *data = xcalloc(sizeof(*data), 1);
data->name = name;
+ if(getenv("GIT_TRANSPORT_HELPER_DEBUG"))
+ debug = 1;
+
transport->data = data;
transport->set_option = set_helper_option;
transport->get_refs_list = get_refs_list;