memcached_server_add() now works so you can connect to host other then
author <brian@gir.local> <>
Tue, 18 Sep 2007 05:36:24 +0000 (07:36 +0200)
committer <brian@gir.local> <>
Tue, 18 Sep 2007 05:36:24 +0000 (07:36 +0200)
localhost.

More error checking on failures (and failures cascading properly).

include/memcached.h
lib/Makefile.am
lib/memcached.c
lib/memcached_connect.c
lib/memcached_delete.c [new file with mode: 0644]
lib/memcached_get.c
lib/memcached_stats.c
lib/memcached_storage.c

index a798fef0b755f39e244877e2c3b0585f82d9aa16..9ab209d3da8f158f1850c607ca7185f2b1fe2eaf 100644 (file)
@@ -22,6 +22,7 @@
 #include <limits.h>
 #include <assert.h>
 #include <time.h>
+#include <errno.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -29,6 +30,7 @@ extern "C" {
 
 typedef struct memcached_st memcached_st;
 typedef struct memcached_stat_st memcached_stat_st;
+typedef struct memcached_host_st memcached_host_st;
 
 #define MEMCACHED_DEFAULT_PORT 11211
 #define MEMCACHED_DEFAULT_COMMAND_SIZE 350
@@ -60,6 +62,12 @@ typedef enum {
   MEMCACHED_ALLOCATED= 1,
 } memcached_allocated;
 
+struct memcached_host_st {
+  char *hostname;
+  unsigned int port;
+  memcached_host_st *next;
+};
+
 struct memcached_stat_st {
   unsigned int pid;
   unsigned int uptime;
@@ -93,6 +101,7 @@ struct memcached_st {
   memcached_allocated is_allocated;
   int fd;
   char connected;
+  memcached_host_st *hosts;
 };
 
 /* Public API */
@@ -128,7 +137,7 @@ char *memcached_get(memcached_st *ptr, char *key, size_t key_length,
                     size_t *value_length, 
                     uint16_t *flags,
                     memcached_return *error);
-void memcached_server_add(memcached_st *ptr, char *server_name, unsigned int port);
+memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigned int port);
 char *memcached_strerror(memcached_st *ptr, memcached_return rc);
 
 /* These are all private, do not use. */
index 8be9da86d7bb1536d6b687d450e677cf0a79af01..9cd6688fc98b7b6e1083027344e6c19fcdb773da 100644 (file)
@@ -7,4 +7,5 @@ libmemcached_la_SOURCES = memcached.c \
                          memcached_response.c \\r
                          memcached_get.c \\r
                          memcached_storage.c \\r
+                         memcached_delete.c \\r
                          memcached_stats.c\r
index 1ceee0086c73054e20102da39f0a6d195020d8c4..944e0f438d1f8d19117786b7c5c9a6b10381b19e 100644 (file)
@@ -24,36 +24,6 @@ memcached_st *memcached_init(memcached_st *ptr)
   return ptr;
 }
 
-void memcached_server_add(memcached_st *ptr, char *server_name, unsigned int port)
-{
-}
-
-
-memcached_return memcached_delete(memcached_st *ptr, char *key, size_t key_length,
-                                  time_t expiration)
-{
-  size_t send_length;
-  memcached_return rc;
-  char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
-
-  rc= memcached_connect(ptr);
-
-  if (expiration)
-    send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
-                          "delete %.*s %u\r\n", key_length, key, expiration);
-  else
-    send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
-                          "delete %.*s\r\n", key_length, key);
-  if ((write(ptr->fd, buffer, send_length) == -1))
-  {
-    fprintf(stderr, "failed set on %.*s TCP\n", key_length+1, key);
-
-    return MEMCACHED_WRITE_FAILURE;
-  }
-
-  return memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE);
-}
-
 memcached_return memcached_increment(memcached_st *ptr, char *key, size_t key_length,
                                      unsigned int count)
 {
@@ -107,9 +77,22 @@ memcached_return memcached_quit(memcached_st *ptr)
 
 void memcached_deinit(memcached_st *ptr)
 {
-  if (ptr->fd == -1)
+  memcached_host_st *host_ptr;
+
+  if (ptr->fd > 0)
     close(ptr->fd);
 
+  for (host_ptr= ptr->hosts; host_ptr;)
+  {
+    memcached_host_st *temp;
+
+    temp= host_ptr;
+    host_ptr= host_ptr->next;
+    if (temp->hostname)
+      free(temp->hostname);
+    free(temp);
+  }
+
   if (ptr->is_allocated == MEMCACHED_ALLOCATED)
     free(ptr);
   else
index 8a6acdd7e5d5430628d2a49c066ac5ece5ffe281..5b3644a18b198053620f1974b5b773389689cf9b 100644 (file)
 #include <memcached.h>
 
-memcached_return memcached_connect(memcached_st *ptr)
+memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigned int port)
 {
-  int rc;
-  struct sockaddr_in localAddr, servAddr;
-  struct hostent *h;
-  char *server_name= "localhost";
+  memcached_host_st *host_ptr, *prev_ptr;
 
-  if (ptr->connected)
-    return MEMCACHED_SUCCESS;
+  if (!port)
+    port= MEMCACHED_DEFAULT_PORT; 
 
+  if (!hostname)
+    hostname= "localhost"; 
 
-  if ((h= gethostbyname(server_name)) == NULL)
+  if (ptr->hosts)
+  {
+    for (host_ptr= ptr->hosts; host_ptr; host_ptr= host_ptr->next)
+      prev_ptr= host_ptr;
+    host_ptr= (memcached_host_st *)malloc(sizeof(memcached_host_st));
+    if (!host_ptr)
+      return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+    prev_ptr->next= host_ptr;
+  }
+  else
   {
-    fprintf(stderr, "unknown host '%s'\n", server_name);
-    return MEMCACHED_HOST_LOCKUP_FAILURE;
+    ptr->hosts=
+      host_ptr= (memcached_host_st *)malloc(sizeof(memcached_host_st));
+    if (!host_ptr)
+      return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
   }
 
-  servAddr.sin_family= h->h_addrtype;
-  memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
-  servAddr.sin_port = htons(MEMCACHED_DEFAULT_PORT);
+  memset(host_ptr, 0, sizeof(memcached_host_st));
+  host_ptr->hostname= (char *)malloc(sizeof(char) * strlen(hostname));
 
-  /* Create the socket */
-  if ((ptr->fd= socket(AF_INET, SOCK_STREAM, 0)) < 0)
+  if (!host_ptr->hostname)
   {
-    fprintf(stderr, "cannot open socket");
-    return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
+    free(host_ptr);
+    return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
   }
+  memcpy(host_ptr->hostname, hostname, strlen(hostname));
+  host_ptr->port= port;
+
+  return MEMCACHED_SUCCESS;
+}
 
+memcached_return memcached_connect(memcached_st *ptr)
+{
+  struct sockaddr_in localAddr, servAddr;
+  struct hostent *h;
+  memcached_host_st *host_ptr;
 
-  /* bind any port number */
-  localAddr.sin_family = AF_INET;
-  localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
-  localAddr.sin_port = htons(0);
+  if (ptr->connected)
+    return MEMCACHED_SUCCESS;
 
-  if (bind(ptr->fd, (struct sockaddr *) &localAddr, sizeof(localAddr)) < 0)
+  if (!ptr->hosts)
   {
-    fprintf(stderr, "cannot bind port TCP %u\n", MEMCACHED_DEFAULT_PORT);
-    return(MEMCACHED_CONNECTION_BIND_FAILURE);
+    memcached_return rc;
+    rc= memcached_server_add(ptr, NULL, 0);
+
+    if (rc != MEMCACHED_SUCCESS)
+      return rc;
   }
 
-  /* connect to server */
-  if (connect(ptr->fd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
+
+  for (host_ptr= ptr->hosts; host_ptr; host_ptr= host_ptr->next)
   {
-    fprintf(stderr, "cannot connect to host '%s'\n", server_name);
-    return MEMCACHED_HOST_LOCKUP_FAILURE;
+    if ((h= gethostbyname(host_ptr->hostname)) == NULL)
+    {
+      fprintf(stderr, "unknown host '%s'\n", host_ptr->hostname);
+      return MEMCACHED_HOST_LOCKUP_FAILURE;
+    }
+
+    servAddr.sin_family= h->h_addrtype;
+    memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
+    servAddr.sin_port = htons(host_ptr->port);
+
+    /* Create the socket */
+    if ((ptr->fd= socket(AF_INET, SOCK_STREAM, 0)) < 0)
+    {
+      fprintf(stderr, "cannot open socket");
+      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);
+
+    if (bind(ptr->fd, (struct sockaddr *) &localAddr, sizeof(localAddr)) < 0)
+    {
+      fprintf(stderr, "cannot bind port TCP %u\n", host_ptr->port);
+      return(MEMCACHED_CONNECTION_BIND_FAILURE);
+    }
+
+    /* connect to server */
+    if (connect(ptr->fd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
+    {
+      fprintf(stderr, "cannot connect to host '%s' (%u)  (error: %s)\n", host_ptr->hostname, 
+              host_ptr->port,
+              strerror(errno));
+      return MEMCACHED_HOST_LOCKUP_FAILURE;
+    }
   }
 
   ptr->connected= 1;
diff --git a/lib/memcached_delete.c b/lib/memcached_delete.c
new file mode 100644 (file)
index 0000000..98aac14
--- /dev/null
@@ -0,0 +1,26 @@
+#include <memcached.h>
+
+memcached_return memcached_delete(memcached_st *ptr, char *key, size_t key_length,
+                                  time_t expiration)
+{
+  size_t send_length;
+  memcached_return rc;
+  char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+
+  rc= memcached_connect(ptr);
+
+  if (expiration)
+    send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
+                          "delete %.*s %u\r\n", key_length, key, expiration);
+  else
+    send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
+                          "delete %.*s\r\n", key_length, key);
+  if ((write(ptr->fd, buffer, send_length) == -1))
+  {
+    fprintf(stderr, "failed set on %.*s TCP\n", key_length+1, key);
+
+    return MEMCACHED_WRITE_FAILURE;
+  }
+
+  return memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE);
+}
index ffecba29b9a45535260dae71d4cc94f4fb91ce1b..1b53b11973cad78f1d7934bd1d17cdda31498d3c 100644 (file)
@@ -11,6 +11,9 @@ char *memcached_get(memcached_st *ptr, char *key, size_t key_length,
 
   *error= memcached_connect(ptr);
 
+  if (*error != MEMCACHED_SUCCESS)
+    return NULL;
+
   send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "get %.*s\r\n", 
                         key_length, key);
   if (*error != MEMCACHED_SUCCESS)
index 457bdc9c4cc1a48a6f4528c88ba55d608ce8f499..8fe5c822fa134252e1e99fe3350018687e9e2af6 100644 (file)
@@ -132,6 +132,9 @@ memcached_return memcached_stat_hostname(memcached_stat_st *stat, char *args,
 
   rc= memcached_connect(&memc);
 
+  if (rc != MEMCACHED_SUCCESS)
+    return rc;
+
   if (args)
     send_length= snprintf(buffer, HUGE_STRING_LEN, 
                           "stats %s\r\n", args);
@@ -163,13 +166,11 @@ memcached_return memcached_stat_hostname(memcached_stat_st *stat, char *args,
       for (end_ptr= string_ptr; *end_ptr != ' '; end_ptr++);
       key= string_ptr;
       key[(size_t)(end_ptr-string_ptr)]= 0;
-      printf("Key %s\n", key);
 
       string_ptr= end_ptr + 1;
       for (end_ptr= string_ptr; *end_ptr != '\r'; end_ptr++);
       value= string_ptr;
       value[(size_t)(end_ptr-string_ptr)]= 0;
-      printf("Value %s\n", value);
       string_ptr= end_ptr + 2;
       set_data(stat, key, value);
     }
index a40296dffca76384d2d8e6cc24e675190adb4a8a..5ed2fd557e79099457ff4cb11363688b4a4658a7 100644 (file)
@@ -22,6 +22,9 @@ static memcached_return memcached_send(memcached_st *ptr,
 
   rc= memcached_connect(ptr);
 
+  if (rc != MEMCACHED_SUCCESS)
+    return rc;
+
   send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
                         "%s %.*s %u %u %u\r\n", verb,
                         key_length, key, flags, expiration, value_length);