Commit f77d4f7f by Vicent Martí

Merge pull request #437 from carlosmn/networking-windows

Fix networking on Windows
parents dc8e3096 bad53552
...@@ -77,7 +77,7 @@ int gitno_connect(const char *host, const char *port) ...@@ -77,7 +77,7 @@ int gitno_connect(const char *host, const char *port)
struct addrinfo *info, *p; struct addrinfo *info, *p;
struct addrinfo hints; struct addrinfo hints;
int ret, error = GIT_SUCCESS; int ret, error = GIT_SUCCESS;
int s; GIT_SOCKET s;
memset(&hints, 0x0, sizeof(struct addrinfo)); memset(&hints, 0x0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
...@@ -92,7 +92,11 @@ int gitno_connect(const char *host, const char *port) ...@@ -92,7 +92,11 @@ int gitno_connect(const char *host, const char *port)
for (p = info; p != NULL; p = p->ai_next) { for (p = info; p != NULL; p = p->ai_next) {
s = socket(p->ai_family, p->ai_socktype, p->ai_protocol); s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
#ifdef GIT_WIN32
if (s == INVALID_SOCKET) {
#else
if (s < 0) { if (s < 0) {
#endif
error = GIT_EOSERR; error = GIT_EOSERR;
goto cleanup; goto cleanup;
} }
...@@ -109,19 +113,21 @@ int gitno_connect(const char *host, const char *port) ...@@ -109,19 +113,21 @@ int gitno_connect(const char *host, const char *port)
} }
/* Oops, we couldn't connect to any address */ /* Oops, we couldn't connect to any address */
error = GIT_EOSERR; error = git__throw(GIT_EOSERR, "Failed to connect: %s", strerror(errno));
cleanup: cleanup:
freeaddrinfo(info); freeaddrinfo(info);
return error; return error;
} }
int gitno_send(int s, const char *msg, size_t len, int flags) int gitno_send(GIT_SOCKET s, const char *msg, size_t len, int flags)
{ {
int ret; int ret;
size_t off = 0; size_t off = 0;
while (off < len) { while (off < len) {
errno = 0;
ret = send(s, msg + off, len - off, flags); ret = send(s, msg + off, len - off, flags);
if (ret < 0) if (ret < 0)
return git__throw(GIT_EOSERR, "Error sending data: %s", strerror(errno)); return git__throw(GIT_EOSERR, "Error sending data: %s", strerror(errno));
...@@ -132,6 +138,18 @@ int gitno_send(int s, const char *msg, size_t len, int flags) ...@@ -132,6 +138,18 @@ int gitno_send(int s, const char *msg, size_t len, int flags)
return off; return off;
} }
#ifdef GIT_WIN32
int gitno_close(GIT_SOCKET s)
{
return closesocket(s) == SOCKET_ERROR ? -1 : 0;
}
#else
int gitno_close(GIT_SOCKET s)
{
return close(s);
}
#endif
int gitno_select_in(gitno_buffer *buf, long int sec, long int usec) int gitno_select_in(gitno_buffer *buf, long int sec, long int usec)
{ {
fd_set fds; fd_set fds;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#ifndef GIT_WIN32 #ifndef GIT_WIN32
typedef int GIT_SOCKET; typedef int GIT_SOCKET;
#else #else
typedef unsigned int GIT_SOCKET; typedef SOCKET GIT_SOCKET;
#endif #endif
typedef struct gitno_buffer { typedef struct gitno_buffer {
...@@ -26,7 +26,8 @@ void gitno_consume(gitno_buffer *buf, const char *ptr); ...@@ -26,7 +26,8 @@ void gitno_consume(gitno_buffer *buf, const char *ptr);
void gitno_consume_n(gitno_buffer *buf, size_t cons); void gitno_consume_n(gitno_buffer *buf, size_t cons);
int gitno_connect(const char *host, const char *port); int gitno_connect(const char *host, const char *port);
int gitno_send(int s, const char *msg, size_t len, int flags); int gitno_send(GIT_SOCKET s, const char *msg, size_t len, int flags);
int gitno_close(GIT_SOCKET s);
int gitno_select_in(gitno_buffer *buf, long int sec, long int usec); int gitno_select_in(gitno_buffer *buf, long int sec, long int usec);
int gitno_extract_host_and_port(char **host, char **port, const char *url, const char *default_port); int gitno_extract_host_and_port(char **host, char **port, const char *url, const char *default_port);
......
...@@ -52,6 +52,9 @@ typedef struct { ...@@ -52,6 +52,9 @@ typedef struct {
enum last_cb last_cb; enum last_cb last_cb;
char *content_type; char *content_type;
char *service; char *service;
#ifdef GIT_WIN32
WSADATA wsd;
#endif
} transport_http; } transport_http;
static int gen_request(git_buf *buf, const char *url, const char *host, const char *service) static int gen_request(git_buf *buf, const char *url, const char *host, const char *service)
...@@ -76,7 +79,8 @@ static int gen_request(git_buf *buf, const char *url, const char *host, const ch ...@@ -76,7 +79,8 @@ static int gen_request(git_buf *buf, const char *url, const char *host, const ch
static int do_connect(transport_http *t, const char *service) static int do_connect(transport_http *t, const char *service)
{ {
git_buf request = GIT_BUF_INIT; git_buf request = GIT_BUF_INIT;
int s = -1, error; int error;
int s;
const char *url, *prefix; const char *url, *prefix;
char *host = NULL, *port = NULL; char *host = NULL, *port = NULL;
...@@ -358,10 +362,14 @@ static int http_close(git_transport *transport) ...@@ -358,10 +362,14 @@ static int http_close(git_transport *transport)
transport_http *t = (transport_http *) transport; transport_http *t = (transport_http *) transport;
int error; int error;
error = close(t->socket); error = gitno_close(t->socket);
if (error < 0) if (error < 0)
return git__throw(GIT_EOSERR, "Failed to close the socket: %s", strerror(errno)); return git__throw(GIT_EOSERR, "Failed to close the socket: %s", strerror(errno));
#ifdef GIT_WIN32
WSACleanup();
#endif
return GIT_SUCCESS; return GIT_SUCCESS;
} }
...@@ -388,6 +396,9 @@ static void http_free(git_transport *transport) ...@@ -388,6 +396,9 @@ static void http_free(git_transport *transport)
int git_transport_http(git_transport **out) int git_transport_http(git_transport **out)
{ {
transport_http *t; transport_http *t;
#ifdef GIT_WIN32
int ret;
#endif
t = git__malloc(sizeof(transport_http)); t = git__malloc(sizeof(transport_http));
if (t == NULL) if (t == NULL)
...@@ -402,5 +413,13 @@ int git_transport_http(git_transport **out) ...@@ -402,5 +413,13 @@ int git_transport_http(git_transport **out)
*out = (git_transport *) t; *out = (git_transport *) t;
#ifdef GIT_WIN32
ret = WSAStartup(MAKEWORD(2,2), &t->wsd);
if (ret != 0) {
http_free(*out);
return git__throw(GIT_EOSERR, "Winsock init failed");
}
#endif
return GIT_SUCCESS; return GIT_SUCCESS;
} }
...@@ -22,10 +22,13 @@ ...@@ -22,10 +22,13 @@
typedef struct { typedef struct {
git_transport parent; git_transport parent;
int socket; GIT_SOCKET socket;
git_vector refs; git_vector refs;
git_remote_head **heads; git_remote_head **heads;
git_transport_caps caps; git_transport_caps caps;
#ifdef GIT_WIN32
WSADATA wsd;
#endif
} transport_git; } transport_git;
/* /*
...@@ -35,10 +38,11 @@ typedef struct { ...@@ -35,10 +38,11 @@ typedef struct {
*/ */
static int gen_proto(char **out, int *outlen, const char *cmd, const char *url) static int gen_proto(char **out, int *outlen, const char *cmd, const char *url)
{ {
char *delim, *repo, *ptr; char *delim, *repo;
char default_command[] = "git-upload-pack"; char default_command[] = "git-upload-pack";
char host[] = "host="; char host[] = "host=";
int len; int len;
git_buf buf = GIT_BUF_INIT;
delim = strchr(url, '/'); delim = strchr(url, '/');
if (delim == NULL) if (delim == NULL)
...@@ -53,22 +57,21 @@ static int gen_proto(char **out, int *outlen, const char *cmd, const char *url) ...@@ -53,22 +57,21 @@ static int gen_proto(char **out, int *outlen, const char *cmd, const char *url)
if (cmd == NULL) if (cmd == NULL)
cmd = default_command; cmd = default_command;
len = 4 + strlen(cmd) + 1 + strlen(repo) + 1 + strlen(host) + (delim - url) + 2; len = 4 + strlen(cmd) + 1 + strlen(repo) + 1 + strlen(host) + (delim - url) + 1 + 1;
*out = git__malloc(len); git_buf_grow(&buf, len);
if (*out == NULL)
return GIT_ENOMEM; git_buf_printf(&buf, "%04x%s %s%c%s", len, cmd, repo, 0, host);
git_buf_put(&buf, url, delim - url);
git_buf_putc(&buf, '\0');
*outlen = len - 1; *outlen = len;
ptr = *out; *out = buf.ptr;
memset(ptr, 0x0, len);
/* We expect the return value to be > len - 1 so don't bother checking it */
snprintf(ptr, len -1, "%04x%s %s%c%s%s", len - 1, cmd, repo, 0, host, url);
return GIT_SUCCESS; return GIT_SUCCESS;
} }
static int send_request(int s, const char *cmd, const char *url) static int send_request(GIT_SOCKET s, const char *cmd, const char *url)
{ {
int error, len; int error, len;
char *msg = NULL; char *msg = NULL;
...@@ -91,7 +94,7 @@ cleanup: ...@@ -91,7 +94,7 @@ cleanup:
*/ */
static int do_connect(transport_git *t, const char *url) static int do_connect(transport_git *t, const char *url)
{ {
int s = -1; GIT_SOCKET s;
char *host, *port; char *host, *port;
const char prefix[] = "git://"; const char prefix[] = "git://";
int error, connected = 0; int error, connected = 0;
...@@ -502,15 +505,18 @@ static int git_download_pack(char **out, git_transport *transport, git_repositor ...@@ -502,15 +505,18 @@ static int git_download_pack(char **out, git_transport *transport, git_repositor
static int git_close(git_transport *transport) static int git_close(git_transport *transport)
{ {
transport_git *t = (transport_git*) transport; transport_git *t = (transport_git*) transport;
int s = t->socket;
int error; int error;
/* Can't do anything if there's an error, so don't bother checking */ /* Can't do anything if there's an error, so don't bother checking */
git_pkt_send_flush(s); git_pkt_send_flush(t->socket);
error = close(s); error = gitno_close(t->socket);
if (error < 0) if (error < 0)
error = git__throw(GIT_EOSERR, "Failed to close socket"); error = git__throw(GIT_EOSERR, "Failed to close socket");
#ifdef GIT_WIN32
WSACleanup();
#endif
return error; return error;
} }
...@@ -534,6 +540,9 @@ static void git_free(git_transport *transport) ...@@ -534,6 +540,9 @@ static void git_free(git_transport *transport)
int git_transport_git(git_transport **out) int git_transport_git(git_transport **out)
{ {
transport_git *t; transport_git *t;
#ifdef GIT_WIN32
int ret;
#endif
t = git__malloc(sizeof(transport_git)); t = git__malloc(sizeof(transport_git));
if (t == NULL) if (t == NULL)
...@@ -554,5 +563,13 @@ int git_transport_git(git_transport **out) ...@@ -554,5 +563,13 @@ int git_transport_git(git_transport **out)
*out = (git_transport *) t; *out = (git_transport *) t;
#ifdef GIT_WIN32
ret = WSAStartup(MAKEWORD(2,2), &t->wsd);
if (ret != 0) {
git_free(*out);
return git__throw(GIT_EOSERR, "Winsock init failed");
}
#endif
return GIT_SUCCESS; return GIT_SUCCESS;
} }
...@@ -201,16 +201,19 @@ static void local_free(git_transport *transport) ...@@ -201,16 +201,19 @@ static void local_free(git_transport *transport)
unsigned int i; unsigned int i;
transport_local *t = (transport_local *) transport; transport_local *t = (transport_local *) transport;
git_vector *vec = t->refs; git_vector *vec = t->refs;
git_remote_head *h;
assert(transport); assert(transport);
for (i = 0; i < vec->length; ++i) { if (t->refs != NULL) {
git_remote_head *h = git_vector_get(vec, i); git_vector_foreach (vec, i, h) {
free(h->name); free(h->name);
free(h); free(h);
} }
git_vector_free(vec); git_vector_free(vec);
free(vec); free(vec);
}
git_repository_free(t->repo); git_repository_free(t->repo);
free(t->parent.url); free(t->parent.url);
free(t); free(t);
...@@ -228,6 +231,8 @@ int git_transport_local(git_transport **out) ...@@ -228,6 +231,8 @@ int git_transport_local(git_transport **out)
if (t == NULL) if (t == NULL)
return GIT_ENOMEM; return GIT_ENOMEM;
memset(t, 0x0, sizeof(transport_local));
t->parent.connect = local_connect; t->parent.connect = local_connect;
t->parent.ls = local_ls; t->parent.ls = local_ls;
t->parent.send_wants = local_send_wants; t->parent.send_wants = local_send_wants;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment