summaryrefslogtreecommitdiff
path: root/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'connect.c')
-rw-r--r--connect.c85
1 files changed, 43 insertions, 42 deletions
diff --git a/connect.c b/connect.c
index 57dc20c..ee1d4b4 100644
--- a/connect.c
+++ b/connect.c
@@ -192,7 +192,8 @@ static const char *ai_name(const struct addrinfo *ai)
*/
static int git_tcp_connect_sock(char *host, int flags)
{
- int sockfd = -1, saved_errno = 0;
+ struct strbuf error_message = STRBUF_INIT;
+ int sockfd = -1;
const char *port = STR(DEFAULT_GIT_PORT);
struct addrinfo hints, *ai0, *ai;
int gai;
@@ -216,21 +217,15 @@ static int git_tcp_connect_sock(char *host, int flags)
if (flags & CONNECT_VERBOSE)
fprintf(stderr, "done.\nConnecting to %s (port %s) ... ", host, port);
- for (ai0 = ai; ai; ai = ai->ai_next) {
+ for (ai0 = ai; ai; ai = ai->ai_next, cnt++) {
sockfd = socket(ai->ai_family,
ai->ai_socktype, ai->ai_protocol);
- if (sockfd < 0) {
- saved_errno = errno;
- continue;
- }
- if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
- saved_errno = errno;
- fprintf(stderr, "%s[%d: %s]: errno=%s\n",
- host,
- cnt,
- ai_name(ai),
- strerror(saved_errno));
- close(sockfd);
+ if ((sockfd < 0) ||
+ (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0)) {
+ strbuf_addf(&error_message, "%s[%d: %s]: errno=%s\n",
+ host, cnt, ai_name(ai), strerror(errno));
+ if (0 <= sockfd)
+ close(sockfd);
sockfd = -1;
continue;
}
@@ -242,11 +237,13 @@ static int git_tcp_connect_sock(char *host, int flags)
freeaddrinfo(ai0);
if (sockfd < 0)
- die("unable to connect a socket (%s)", strerror(saved_errno));
+ die("unable to connect to %s:\n%s", host, error_message.buf);
if (flags & CONNECT_VERBOSE)
fprintf(stderr, "done.\n");
+ strbuf_release(&error_message);
+
return sockfd;
}
@@ -257,7 +254,8 @@ static int git_tcp_connect_sock(char *host, int flags)
*/
static int git_tcp_connect_sock(char *host, int flags)
{
- int sockfd = -1, saved_errno = 0;
+ struct strbuf error_message = STRBUF_INIT;
+ int sockfd = -1;
const char *port = STR(DEFAULT_GIT_PORT);
char *ep;
struct hostent *he;
@@ -287,25 +285,21 @@ static int git_tcp_connect_sock(char *host, int flags)
fprintf(stderr, "done.\nConnecting to %s (port %s) ... ", host, port);
for (cnt = 0, ap = he->h_addr_list; *ap; ap++, cnt++) {
- sockfd = socket(he->h_addrtype, SOCK_STREAM, 0);
- if (sockfd < 0) {
- saved_errno = errno;
- continue;
- }
-
memset(&sa, 0, sizeof sa);
sa.sin_family = he->h_addrtype;
sa.sin_port = htons(nport);
memcpy(&sa.sin_addr, *ap, he->h_length);
- if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
- saved_errno = errno;
- fprintf(stderr, "%s[%d: %s]: errno=%s\n",
+ sockfd = socket(he->h_addrtype, SOCK_STREAM, 0);
+ if ((sockfd < 0) ||
+ connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
+ strbuf_addf(&error_message, "%s[%d: %s]: errno=%s\n",
host,
cnt,
inet_ntoa(*(struct in_addr *)&sa.sin_addr),
- strerror(saved_errno));
- close(sockfd);
+ strerror(errno));
+ if (0 <= sockfd)
+ close(sockfd);
sockfd = -1;
continue;
}
@@ -316,7 +310,7 @@ static int git_tcp_connect_sock(char *host, int flags)
}
if (sockfd < 0)
- die("unable to connect a socket (%s)", strerror(saved_errno));
+ die("unable to connect to %s:\n%s", host, error_message.buf);
if (flags & CONNECT_VERBOSE)
fprintf(stderr, "done.\n");
@@ -395,26 +389,28 @@ static int git_use_proxy(const char *host)
return (git_proxy_command && *git_proxy_command);
}
-static void git_proxy_connect(int fd[2], char *host)
+static struct child_process *git_proxy_connect(int fd[2], char *host)
{
const char *port = STR(DEFAULT_GIT_PORT);
- const char *argv[4];
- struct child_process proxy;
+ const char **argv;
+ struct child_process *proxy;
get_host_and_port(&host, &port);
+ argv = xmalloc(sizeof(*argv) * 4);
argv[0] = git_proxy_command;
argv[1] = host;
argv[2] = port;
argv[3] = NULL;
- memset(&proxy, 0, sizeof(proxy));
- proxy.argv = argv;
- proxy.in = -1;
- proxy.out = -1;
- if (start_command(&proxy))
+ proxy = xcalloc(1, sizeof(*proxy));
+ proxy->argv = argv;
+ proxy->in = -1;
+ proxy->out = -1;
+ if (start_command(proxy))
die("cannot start proxy %s", argv[0]);
- fd[0] = proxy.out; /* read from proxy stdout */
- fd[1] = proxy.in; /* write to proxy stdin */
+ fd[0] = proxy->out; /* read from proxy stdout */
+ fd[1] = proxy->in; /* write to proxy stdin */
+ return proxy;
}
#define MAX_CMD_LEN 1024
@@ -455,7 +451,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
char *host, *path;
char *end;
int c;
- struct child_process *conn;
+ struct child_process *conn = &no_fork;
enum protocol protocol = PROTO_LOCAL;
int free_path = 0;
char *port = NULL;
@@ -540,7 +536,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
*/
char *target_host = xstrdup(host);
if (git_use_proxy(host))
- git_proxy_connect(fd, host);
+ conn = git_proxy_connect(fd, host);
else
git_tcp_connect(fd, host, flags);
/*
@@ -558,7 +554,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
free(url);
if (free_path)
free(path);
- return &no_fork;
+ return conn;
}
conn = xcalloc(1, sizeof(*conn));
@@ -607,10 +603,15 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
return conn;
}
+int git_connection_is_socket(struct child_process *conn)
+{
+ return conn == &no_fork;
+}
+
int finish_connect(struct child_process *conn)
{
int code;
- if (!conn || conn == &no_fork)
+ if (!conn || git_connection_is_socket(conn))
return 0;
code = finish_command(conn);