This fixes a couple problems when exiting due to signal:
[rrdtool.git] / src / rrd_daemon.c
index 0816526..c438028 100644 (file)
@@ -1479,12 +1479,11 @@ static void *connection_thread_main (void *args) /* {{{ */
 
     status = handle_request (fd, buffer, /*buffer_size=*/ status);
     if (status != 0)
-    {
-      close (fd);
       break;
-    }
   }
 
+  close(fd);
+
   self = pthread_self ();
   /* Remove this thread from the connection threads list */
   pthread_mutex_lock (&connection_threads_lock);
@@ -1563,14 +1562,21 @@ static int open_listen_socket_unix (const char *path) /* {{{ */
   return (0);
 } /* }}} int open_listen_socket_unix */
 
-static int open_listen_socket (const char *addr) /* {{{ */
+static int open_listen_socket (const char *addr_orig) /* {{{ */
 {
   struct addrinfo ai_hints;
   struct addrinfo *ai_res;
   struct addrinfo *ai_ptr;
+  char addr_copy[NI_MAXHOST];
+  char *addr;
+  char *port;
   int status;
 
-  assert (addr != NULL);
+  assert (addr_orig != NULL);
+
+  strncpy (addr_copy, addr_orig, sizeof (addr_copy));
+  addr_copy[sizeof (addr_copy) - 1] = 0;
+  addr = addr_copy;
 
   if (strncmp ("unix:", addr, strlen ("unix:")) == 0)
     return (open_listen_socket_unix (addr + strlen ("unix:")));
@@ -1585,8 +1591,46 @@ static int open_listen_socket (const char *addr) /* {{{ */
   ai_hints.ai_family = AF_UNSPEC;
   ai_hints.ai_socktype = SOCK_STREAM;
 
+  port = NULL;
+ if (*addr == '[') /* IPv6+port format */
+  {
+    /* `addr' is something like "[2001:780:104:2:211:24ff:feab:26f8]:12345" */
+    addr++;
+
+    port = strchr (addr, ']');
+    if (port == NULL)
+    {
+      RRDD_LOG (LOG_ERR, "open_listen_socket: Malformed address: %s",
+          addr_orig);
+      return (-1);
+    }
+    *port = 0;
+    port++;
+
+    if (*port == ':')
+      port++;
+    else if (*port == 0)
+      port = NULL;
+    else
+    {
+      RRDD_LOG (LOG_ERR, "open_listen_socket: Garbage after address: %s",
+          port);
+      return (-1);
+    }
+  } /* if (*addr = ']') */
+  else if (strchr (addr, '.') != NULL) /* Hostname or IPv4 */
+  {
+    port = rindex(addr, ':');
+    if (port != NULL)
+    {
+      *port = 0;
+      port++;
+    }
+  }
   ai_res = NULL;
-  status = getaddrinfo (addr, RRDCACHED_DEFAULT_PORT, &ai_hints, &ai_res);
+  status = getaddrinfo (addr,
+                        port == NULL ? RRDCACHED_DEFAULT_PORT : port,
+                        &ai_hints, &ai_res);
   if (status != 0)
   {
     RRDD_LOG (LOG_ERR, "open_listen_socket: getaddrinfo(%s) failed: "
@@ -1598,6 +1642,7 @@ static int open_listen_socket (const char *addr) /* {{{ */
   {
     int fd;
     listen_socket_t *temp;
+    int one = 1;
 
     temp = (listen_socket_t *) realloc (listen_fds,
         sizeof (listen_fds[0]) * (listen_fds_num + 1));
@@ -1616,6 +1661,8 @@ static int open_listen_socket (const char *addr) /* {{{ */
       continue;
     }
 
+    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+
     status = bind (fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
     if (status != 0)
     {
@@ -1700,8 +1747,12 @@ static void *listen_thread_main (void *args __attribute__((unused))) /* {{{ */
       pollfds[i].revents = 0;
     }
 
-    status = poll (pollfds, pollfds_num, /* timeout = */ -1);
-    if (status < 1)
+    status = poll (pollfds, pollfds_num, /* timeout = */ 1000);
+    if (status == 0)
+    {
+      continue; /* timeout */
+    }
+    else if (status < 0)
     {
       status = errno;
       if (status != EINTR)
@@ -2033,17 +2084,19 @@ static int read_options (int argc, char **argv) /* {{{ */
 
       case 'h':
       case '?':
-        printf ("RRDd %s  Copyright (C) 2008 Florian octo Forster\n"
+        printf ("RRDCacheD %s  Copyright (C) 2008 Florian octo Forster\n"
             "\n"
             "Usage: rrdcached [options]\n"
             "\n"
             "Valid options are:\n"
             "  -l <address>  Socket address to listen to.\n"
             "  -w <seconds>  Interval in which to write data.\n"
-            "  -z <delay>    Delay writes up to <delay> seconds to spread load" \
+            "  -z <delay>    Delay writes up to <delay> seconds to spread load\n"
             "  -f <seconds>  Interval in which to flush dead data.\n"
             "  -p <file>     Location of the PID-file.\n"
             "  -b <dir>      Base directory to change to.\n"
+            "  -g            Do not fork and run in the foreground.\n"
+            "  -j <dir>      Directory in which to create the journal files.\n"
             "\n"
             "For more information and a detailed description of all options "
             "please refer\n"