2 * collectd - src/rrdd.c
3 * Copyright (C) 2008 Florian octo Forster
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; only version 2 of the License is applicable.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * Florian octo Forster <octo at verplant.org>
27 struct listen_socket_s
30 char path[PATH_MAX + 1];
32 typedef struct listen_socket_s listen_socket_t;
37 static listen_socket_t *listen_fds = NULL;
38 static size_t listen_fds_num = 0;
40 static int do_shutdown = 0;
42 static pthread_t queue_thread;
47 static void *queue_thread_main (void *args) /* {{{ */
49 while (do_shutdown == 0)
51 syslog (LOG_DEBUG, "queue_thread_main: Just woke up.");
53 } /* while (do_shutdown == 0) */
55 syslog (LOG_DEBUG, "queue_thread_main: Exiting.");
58 } /* }}} void *queue_thread_main */
60 static void sig_int_handler (int signal) /* {{{ */
63 } /* }}} void sig_int_handler */
65 static void sig_term_handler (int signal) /* {{{ */
68 } /* }}} void sig_term_handler */
70 static int open_listen_socket (const char *path) /* {{{ */
73 struct sockaddr_un sa;
74 listen_socket_t *temp;
77 temp = (listen_socket_t *) realloc (listen_fds,
78 sizeof (listen_fds[0]) * (listen_fds_num + 1));
81 syslog (LOG_ERR, "open_listen_socket: realloc failed.\n");
85 memset (listen_fds + listen_fds_num, 0, sizeof (listen_fds[0]));
87 fd = socket (PF_UNIX, SOCK_STREAM, /* protocol = */ 0);
90 syslog (LOG_ERR, "open_listen_socket: socket(2) failed.\n");
94 memset (&sa, 0, sizeof (sa));
95 sa.sun_family = AF_UNIX;
96 strncpy (sa.sun_path, path, sizeof (sa.sun_path) - 1);
98 status = bind (fd, (struct sockaddr *) &sa, sizeof (sa));
101 syslog (LOG_ERR, "open_listen_socket: bind(2) failed.\n");
106 listen_fds[listen_fds_num].fd = fd;
107 strncpy (listen_fds[listen_fds_num].path, path,
108 sizeof (listen_fds[listen_fds_num].path) - 1);
112 } /* }}} int open_listen_socket */
114 static int close_listen_sockets (void) /* {{{ */
118 for (i = 0; i < listen_fds_num; i++)
120 close (listen_fds[i].fd);
121 unlink (listen_fds[i].path);
129 } /* }}} int close_listen_sockets */
131 static void *listen_thread_main (void *args) /* {{{ */
136 status = open_listen_socket (RRDD_SOCK_PATH);
139 syslog (LOG_ERR, "listen_thread_main: open_listen_socket failed.");
143 while (do_shutdown == 0)
145 syslog (LOG_DEBUG, "listen_thread_main: Just woke up.");
147 status = recv (listen_fds[0].fd, buffer, sizeof (buffer),
159 syslog (LOG_ERR, "listen_thread_main: recv failed.");
164 syslog (LOG_DEBUG, "listen_thread_main: Received %i bytes.\n", status);
165 } /* while (do_shutdown == 0) */
167 close_listen_sockets ();
169 syslog (LOG_DEBUG, "listen_thread_main: Exiting.");
172 } /* }}} void *listen_thread_main */
174 static int daemonize (void) /* {{{ */
182 fprintf (stderr, "daemonize: fork(2) failed.\n");
190 /* Change into the /tmp directory. */
193 /* Become session leader */
196 /* Open the first three file descriptors to /dev/null */
201 open ("/dev/null", O_RDWR);
208 memset (&sa, 0, sizeof (sa));
209 sa.sa_handler = sig_int_handler;
210 sigaction (SIGINT, &sa, NULL);
212 memset (&sa, 0, sizeof (sa));
213 sa.sa_handler = sig_term_handler;
214 sigaction (SIGINT, &sa, NULL);
217 openlog ("rrdd", LOG_PID, LOG_DAEMON);
219 memset (&queue_thread, 0, sizeof (queue_thread));
220 status = pthread_create (&queue_thread, /* attr = */ NULL,
221 queue_thread_main, /* args = */ NULL);
224 syslog (LOG_ERR, "daemonize: pthread_create failed.");
229 } /* }}} int daemonize */
231 static int cleanup (void) /* {{{ */
235 pthread_join (queue_thread, /* return = */ NULL);
240 } /* }}} int cleanup */
242 int main (int argc, char **argv)
246 printf ("%s by Florian Forster, Version %s\n",
247 PACKAGE_NAME, PACKAGE_VERSION);
249 status = daemonize ();
252 struct sigaction sigchld;
254 memset (&sigchld, 0, sizeof (sigchld));
255 sigchld.sa_handler = SIG_IGN;
256 sigaction (SIGCHLD, &sigchld, NULL);
260 else if (status != 0)
262 fprintf (stderr, "daemonize failed, exiting.\n");
266 listen_thread_main (NULL);
274 * vim: set sw=2 sts=2 ts=8 et fdm=marker :