Refactor all code to go through memcached_do().
[m6w6/libmemcached] / lib / memcached_connect.c
index 8ffaaef9fb91057e5c3f6ee1c8aba8c9368ccbdc..025fdf6e00e589532a69f33b50ee790d01eba68b 100644 (file)
@@ -3,12 +3,53 @@
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <netinet/tcp.h>
 #include <netdb.h>
 
-memcached_return memcached_real_connect(memcached_st *ptr, unsigned int server_key)
+static memcached_return unix_socket_connect(memcached_st *ptr, unsigned int server_key)
 {
-  struct sockaddr_in localAddr, servAddr;
+  struct sockaddr_un servAddr;
+  socklen_t addrlen;
+
+  if (ptr->hosts[server_key].fd == -1)
+  {
+    if ((ptr->hosts[server_key].fd= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+    {
+      ptr->cached_errno= errno;
+      return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
+    }
+
+    memset(&servAddr, 0, sizeof (struct sockaddr_un));
+    servAddr.sun_family= AF_UNIX;
+    strcpy(servAddr.sun_path, ptr->hosts[server_key].hostname);
+
+    addrlen= strlen(servAddr.sun_path) + sizeof(servAddr.sun_family);
+
+test_connect:
+    if (connect(ptr->hosts[server_key].fd, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)
+    {
+      switch (errno) {
+        /* We are spinning waiting on connect */
+      case EALREADY:
+      case EINPROGRESS:
+      case EINTR:
+        goto test_connect;
+      case EISCONN: /* We were spinning waiting on connect */
+        break;
+      default:
+        ptr->cached_errno= errno;
+        return MEMCACHED_ERRNO;
+      }
+      ptr->connected++;
+    }
+  }
+  return MEMCACHED_SUCCESS;
+}
+
+static memcached_return tcp_connect(memcached_st *ptr, unsigned int server_key)
+{
+  struct sockaddr_in servAddr;
   struct hostent *h;
 
   if (ptr->hosts[server_key].fd == -1)
@@ -18,7 +59,7 @@ memcached_return memcached_real_connect(memcached_st *ptr, unsigned int server_k
 
     if ((h= gethostbyname(ptr->hosts[server_key].hostname)) == NULL)
     {
-      ptr->my_errno= h_errno;
+      ptr->cached_errno= h_errno;
       return MEMCACHED_HOST_LOCKUP_FAILURE;
     }
 
@@ -29,15 +70,10 @@ memcached_return memcached_real_connect(memcached_st *ptr, unsigned int server_k
     /* Create the socket */
     if ((ptr->hosts[server_key].fd= socket(AF_INET, SOCK_STREAM, 0)) < 0)
     {
-      ptr->my_errno= errno;
+      ptr->cached_errno= errno;
       return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
     }
 
-    /* bind any port number */
-    localAddr.sin_family = AF_INET;
-    localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
-    localAddr.sin_port = htons(0);
-
     /* For the moment, not getting a nonblocking mode will note be fatal */
     if (ptr->flags & MEM_NO_BLOCK)
     {
@@ -70,7 +106,7 @@ memcached_return memcached_real_connect(memcached_st *ptr, unsigned int server_k
 
     /* connect to server */
 test_connect:
-    if (connect(ptr->hosts[server_key].fd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
+    if (connect(ptr->hosts[server_key].fd, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)
     {
       switch (errno) {
         /* We are spinning waiting on connect */
@@ -81,7 +117,7 @@ test_connect:
       case EISCONN: /* We were spinning waiting on connect */
         break;
       default:
-        ptr->my_errno= errno;
+        ptr->cached_errno= errno;
         return MEMCACHED_ERRNO;
       }
       ptr->connected++;
@@ -98,15 +134,15 @@ memcached_return memcached_connect(memcached_st *ptr, unsigned int server_key)
   memcached_return rc= MEMCACHED_NO_SERVERS;
   LIBMEMCACHED_MEMCACHED_CONNECT_START();
 
-  if (ptr->connected == ptr->number_of_hosts)
+  if (ptr->connected == ptr->number_of_hosts && ptr->number_of_hosts)
     return MEMCACHED_SUCCESS;
 
-  if (!ptr->hosts)
+  if (ptr->hosts == NULL || ptr->number_of_hosts == 0)
     return MEMCACHED_NO_SERVERS;
 
   /* We need to clean up the multi startup piece */
   if (server_key)
-    rc= memcached_real_connect(ptr, server_key);
+    rc= tcp_connect(ptr, server_key);
   else
   {
     unsigned int x;
@@ -115,7 +151,22 @@ memcached_return memcached_connect(memcached_st *ptr, unsigned int server_key)
     {
       memcached_return possible_rc;
 
-      possible_rc= memcached_real_connect(ptr, x);
+      possible_rc= MEMCACHED_NOT_SUPPORTED; /* Remove warning */
+
+      switch (ptr->hosts[x].type)
+      {
+      case MEMCACHED_CONNECTION_UNKNOWN:
+      case MEMCACHED_CONNECTION_UDP:
+        WATCHPOINT_ASSERT(0);
+        possible_rc= MEMCACHED_NOT_SUPPORTED;
+        break;
+      case MEMCACHED_CONNECTION_TCP:
+        possible_rc= tcp_connect(ptr, x);
+        break;
+      case MEMCACHED_CONNECTION_UNIX_SOCKET:
+        possible_rc= unix_socket_connect(ptr, x);
+        break;
+      }
       rc= MEMCACHED_SUCCESS;
 
       if (possible_rc != MEMCACHED_SUCCESS)