Code

Merge branch 'ew/keepalive'
authorJunio C Hamano <gitster@pobox.com>
Tue, 20 Dec 2011 00:06:32 +0000 (16:06 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 20 Dec 2011 00:06:32 +0000 (16:06 -0800)
* ew/keepalive:
  enable SO_KEEPALIVE for connected TCP sockets

1  2 
connect.c

diff --combined connect.c
index 2a0a0401af6e070125f1ae6d97004f4036af35f6,d725b1794f4a6d272a0cc649f57d99453255f8cc..c8d0ea5d75e89a6b15b62e7057e97947036e11ea
+++ b/connect.c
@@@ -22,7 -22,7 +22,7 @@@ static int check_ref(const char *name, 
        len -= 5;
  
        /* REF_NORMAL means that we don't want the magic fake tag refs */
 -      if ((flags & REF_NORMAL) && check_ref_format(name) < 0)
 +      if ((flags & REF_NORMAL) && check_refname_format(name, 0))
                return 0;
  
        /* REF_HEADS means that we want regular branch heads */
@@@ -53,6 -53,7 +53,6 @@@ static void add_extra_have(struct extra
   * Read all the refs from the other end
   */
  struct ref **get_remote_heads(int in, struct ref **list,
 -                            int nr_match, char **match,
                              unsigned int flags,
                              struct extra_have_objects *extra_have)
  {
@@@ -91,6 -92,8 +91,6 @@@
  
                if (!check_ref(name, name_len, flags))
                        continue;
 -              if (nr_match && !path_match(name, nr_match, match))
 -                      continue;
                ref = alloc_ref(buffer + 41);
                hashcpy(ref->old_sha1, old_sha1);
                *list = ref;
@@@ -105,6 -108,27 +105,6 @@@ int server_supports(const char *feature
                strstr(server_capabilities, feature) != NULL;
  }
  
 -int path_match(const char *path, int nr, char **match)
 -{
 -      int i;
 -      int pathlen = strlen(path);
 -
 -      for (i = 0; i < nr; i++) {
 -              char *s = match[i];
 -              int len = strlen(s);
 -
 -              if (!len || len > pathlen)
 -                      continue;
 -              if (memcmp(path + pathlen - len, s, len))
 -                      continue;
 -              if (pathlen > len && path[pathlen - len - 1] != '/')
 -                      continue;
 -              *s = 0;
 -              return (i + 1);
 -      }
 -      return 0;
 -}
 -
  enum protocol {
        PROTO_LOCAL = 1,
        PROTO_SSH,
@@@ -151,6 -175,15 +151,15 @@@ static void get_host_and_port(char **ho
        }
  }
  
+ 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)
@@@ -215,6 -248,8 +224,8 @@@ static int git_tcp_connect_sock(char *h
        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");
  
   */
  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;
                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;
                }
        }
  
        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);
  
+       enable_keepalive(sockfd);
        if (flags & CONNECT_VERBOSE)
                fprintf(stderr, "done.\n");