summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-12-06 04:39:36 (GMT)
committerJunio C Hamano <gitster@pobox.com>2011-12-06 05:06:53 (GMT)
commite47a8583a20256851e7fc882233e3bd5bf33dc6e (patch)
tree0bdef533393b087b3fc6d560f57289d220a787c7
parentc2857fb8b7903b2bba9217310971e5282549174d (diff)
downloadgit-e47a8583a20256851e7fc882233e3bd5bf33dc6e.zip
git-e47a8583a20256851e7fc882233e3bd5bf33dc6e.tar.gz
git-e47a8583a20256851e7fc882233e3bd5bf33dc6e.tar.bz2
enable SO_KEEPALIVE for connected TCP sockets
Sockets may never receive notification of some link errors, causing "git fetch" or similar processes to hang forever. Enabling keepalive messages allows hung processes to error out after a few minutes/hours depending on the keepalive settings of the system. This is a problem noticed when running non-interactive cronjobs to mirror repositories using "git fetch". Signed-off-by: Eric Wong <normalperson@yhbt.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--connect.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/connect.c b/connect.c
index d2ce57f..d725b17 100644
--- a/connect.c
+++ b/connect.c
@@ -175,6 +175,15 @@ static void get_host_and_port(char **host, const char **port)
}
}
+static void enable_keepalive(int sockfd)
+{
+ int ka = 1;
+
+ if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &ka, sizeof(ka)) < 0)
+ fprintf(stderr, "unable to set SO_KEEPALIVE on socket: %s\n",
+ strerror(errno));
+}
+
#ifndef NO_IPV6
static const char *ai_name(const struct addrinfo *ai)
@@ -239,6 +248,8 @@ static int git_tcp_connect_sock(char *host, int flags)
if (sockfd < 0)
die("unable to connect to %s:\n%s", host, error_message.buf);
+ enable_keepalive(sockfd);
+
if (flags & CONNECT_VERBOSE)
fprintf(stderr, "done.\n");
@@ -315,6 +326,8 @@ static int git_tcp_connect_sock(char *host, int flags)
if (sockfd < 0)
die("unable to connect a socket (%s)", strerror(saved_errno));
+ enable_keepalive(sockfd);
+
if (flags & CONNECT_VERBOSE)
fprintf(stderr, "done.\n");