]> git.meshlink.io Git - catta/commitdiff
* fix memory handling when reading configuration files
authorLennart Poettering <lennart@poettering.net>
Sat, 18 Jun 2005 23:22:20 +0000 (23:22 +0000)
committerLennart Poettering <lennart@poettering.net>
Sat, 18 Jun 2005 23:22:20 +0000 (23:22 +0000)
* implement signal handling in daemon
* correctly increase reference counter for main contexts when running g_main_context_default()

git-svn-id: file:///home/lennart/svn/public/avahi/trunk@128 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

avahi-core/netlink.c
avahi-core/server.c
avahi-daemon/main.c
avahi-daemon/simple-protocol.c
avahi-daemon/static-services.c

index 50ddf5c282aa3442e62fb9627024aac925fdbbc1..ff88b91d5661ed554588b74f88c6d7be18d524a5 100644 (file)
@@ -120,7 +120,6 @@ AvahiNetlink *avahi_netlink_new(GMainContext *context, gint priority, guint32 gr
         NULL
     };
     
-    g_assert(context);
     g_assert(cb);
 
     if ((fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
@@ -140,8 +139,7 @@ AvahiNetlink *avahi_netlink_new(GMainContext *context, gint priority, guint32 gr
     }
 
     nl = g_new(AvahiNetlink, 1);
-    nl->context = context;
-    g_main_context_ref(context);
+    g_main_context_ref(nl->context = context ? context : g_main_context_default());
     nl->fd = fd;
     nl->seq = 0;
     nl->callback = cb;
index 0c0065809bcbf87c2155bed994f9e89ff393a055..d03a2848e78f1dfa84e85b5d66df64aa3d94de59 100644 (file)
@@ -1275,10 +1275,7 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, Avah
     s->fd_legacy_unicast_ipv4 = s->fd_ipv4 >= 0 && s->config.enable_reflector ? avahi_open_legacy_unicast_socket_ipv4() : -1;
     s->fd_legacy_unicast_ipv6 = s->fd_ipv6 >= 0 && s->config.enable_reflector ? avahi_open_legacy_unicast_socket_ipv6() : -1;
 
-    if (c)
-        g_main_context_ref(s->context = c);
-    else
-        s->context = g_main_context_default();
+    g_main_context_ref(c->context = c ? c : g_main_context_default());
 
     /* Prepare IO source registration */
     s->source = g_source_new(&source_funcs, sizeof(GSource) + sizeof(AvahiServer*));
index 4373f9af8bc122732e9ea7f7dd81b7fee4d4ab0b..0d862eab8ef9233d6d74117b2a1ec1e9646a79d3 100644 (file)
@@ -26,6 +26,8 @@
 #include <getopt.h>
 #include <string.h>
 #include <signal.h>
+#include <errno.h>
+#include <string.h>
 
 #include <libdaemon/dfork.h>
 #include <libdaemon/dsignal.h>
@@ -143,7 +145,7 @@ static gint load_config_file(DaemonConfig *config) {
     int r = -1;
     GKeyFile *f = NULL;
     GError *err = NULL;
-    gchar **groups = NULL, **g, **keys = NULL;
+    gchar **groups = NULL, **g, **keys = NULL, *v = NULL;
 
     g_assert(config);
     
@@ -163,27 +165,38 @@ static gint load_config_file(DaemonConfig *config) {
             keys = g_key_file_get_keys(f, *g, NULL, NULL);
 
             for (k = keys; *k; k++) {
+
+                v = g_key_file_get_value(f, *g, *k, NULL);
+                
                 if (g_strcasecmp(*k, "host-name") == 0) {
                     g_free(config->server_config.host_name);
-                    config->server_config.host_name = g_strdup(g_key_file_get_string(f, *g, *k, NULL));
+                    config->server_config.host_name = v;
+                    v = NULL;
                 } else if (g_strcasecmp(*k, "domain-name") == 0) {
                     g_free(config->server_config.domain_name);
-                    config->server_config.domain_name = g_strdup(g_key_file_get_string(f, *g, *k, NULL));
+                    config->server_config.domain_name = v;
+                    v = NULL;
                 } else if (g_strcasecmp(*k, "use-ipv4") == 0)
-                    config->server_config.use_ipv4 = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+                    config->server_config.use_ipv4 = is_yes(v);
                 else if (g_strcasecmp(*k, "use-ipv6") == 0)
-                    config->server_config.use_ipv6 = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+                    config->server_config.use_ipv6 = is_yes(v);
                 else if (g_strcasecmp(*k, "check-response-ttl") == 0)
-                    config->server_config.check_response_ttl = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+                    config->server_config.check_response_ttl = is_yes(v);
                 else if (g_strcasecmp(*k, "use-iff-running") == 0)
-                    config->server_config.use_iff_running = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+                    config->server_config.use_iff_running = is_yes(v);
                 else if (g_strcasecmp(*k, "enable-dbus") == 0)
-                    config->enable_dbus = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+                    config->enable_dbus = is_yes(v);
                 else {
                     fprintf(stderr, "Invalid configuration key \"%s\" in group \"%s\"\n", *k, *g);
                     goto finish;
                 }
+
+                g_free(v);
+                v = NULL;
             }
+        
+            g_strfreev(keys);
+            keys = NULL;
             
         } else if (g_strcasecmp(*g, "publish") == 0) {
             gchar **k;
@@ -191,36 +204,54 @@ static gint load_config_file(DaemonConfig *config) {
             keys = g_key_file_get_keys(f, *g, NULL, NULL);
 
             for (k = keys; *k; k++) {
+
+                v = g_key_file_get_string(f, *g, *k, NULL);
+                
                 if (g_strcasecmp(*k, "publish-addresses") == 0)
-                    config->server_config.publish_addresses = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+                    config->server_config.publish_addresses = is_yes(v);
                 else if (g_strcasecmp(*k, "publish-hinfo") == 0)
-                    config->server_config.publish_hinfo = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+                    config->server_config.publish_hinfo = is_yes(v);
                 else if (g_strcasecmp(*k, "publish-workstation") == 0)
-                    config->server_config.publish_workstation = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+                    config->server_config.publish_workstation = is_yes(v);
                 else if (g_strcasecmp(*k, "publish-domain") == 0)
-                    config->server_config.publish_domain = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+                    config->server_config.publish_domain = is_yes(v);
                 else {
                     fprintf(stderr, "Invalid configuration key \"%s\" in group \"%s\"\n", *k, *g);
                     goto finish;
                 }
+
+                g_free(v);
+                v = NULL;
             }
 
+            g_strfreev(keys);
+            keys = NULL;
+
         } else if (g_strcasecmp(*g, "reflector") == 0) {
             gchar **k;
             
             keys = g_key_file_get_keys(f, *g, NULL, NULL);
 
             for (k = keys; *k; k++) {
+
+                v = g_key_file_get_string(f, *g, *k, NULL);
+                
                 if (g_strcasecmp(*k, "enable-reflector") == 0)
-                    config->server_config.enable_reflector = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+                    config->server_config.enable_reflector = is_yes(v);
                 else if (g_strcasecmp(*k, "reflect-ipv") == 0)
-                    config->server_config.reflect_ipv = is_yes(g_key_file_get_string(f, *g, *k, NULL));
+                    config->server_config.reflect_ipv = is_yes(v);
                 else {
                     fprintf(stderr, "Invalid configuration key \"%s\" in group \"%s\"\n", *k, *g);
                     goto finish;
                 }
+
+                g_free(v);
+                v = NULL;
             }
     
+            g_strfreev(keys);
+            keys = NULL;
+            
         } else {
             fprintf(stderr, "Invalid configuration file group \"%s\".\n", *g);
             goto finish;
@@ -233,6 +264,7 @@ finish:
 
     g_strfreev(groups);
     g_strfreev(keys);
+    g_free(v);
 
     if (err)
         g_error_free (err);
@@ -259,13 +291,61 @@ static void log_function(AvahiLogLevel level, const gchar *txt) {
     daemon_log(log_level_map[level], "%s", txt);
 }
 
+static gboolean signal_callback(GIOChannel *source, GIOCondition condition, gpointer data) {
+    gint sig;
+    g_assert(source);
+
+    if ((sig = daemon_signal_next()) <= 0) {
+        avahi_log_error("daemon_signal_next() failed");
+        return FALSE;
+    }
+
+    switch (sig) {
+        case SIGINT:
+        case SIGQUIT:
+        case SIGTERM:
+            avahi_log_info(
+                "Got %s, quitting.",
+                sig == SIGINT ? "SIGINT" :
+                (sig == SIGQUIT ? "SIGQUIT" : "SIGTERM"));
+            g_main_loop_quit((GMainLoop*) data);
+            break;
+
+        case SIGHUP:
+            avahi_log_info("Got SIGHUP, reloading.");
+            static_service_load();
+            break;
+
+        default:
+            avahi_log_warn("Got spurious signal, ignoring.");
+            break;
+    }
+
+    return TRUE;
+}
+
 static gint run_server(DaemonConfig *config) {
     GMainLoop *loop = NULL;
     gint r = -1;
+    GIOChannel *io = NULL;
+    guint watch_id = (guint) -1;
 
     g_assert(config);
     
     loop = g_main_loop_new(NULL, FALSE);
+
+    if (daemon_signal_init(SIGINT, SIGQUIT, SIGHUP, SIGTERM, 0) < 0) {
+        avahi_log_error("Could not register signal handlers (%s).", strerror(errno));
+        goto finish;
+    }
+
+    if (!(io = g_io_channel_unix_new(daemon_signal_fd()))) {
+        avahi_log_error( "Failed to create signal io channel.");
+        goto finish;
+    }
+
+    g_io_channel_set_close_on_unref(io, FALSE);
+    g_io_add_watch(io, G_IO_IN, signal_callback, loop);
     
     if (simple_protocol_setup(NULL) < 0)
         goto finish;
@@ -285,9 +365,8 @@ static gint run_server(DaemonConfig *config) {
         daemon_retval_send(0);
         r = 0;
     }
-    
-    g_main_loop_run(loop);
 
+    g_main_loop_run(loop);
 
 finish:
     
@@ -303,12 +382,21 @@ finish:
 
     if (avahi_server)
         avahi_server_free(avahi_server);
+
+    daemon_signal_done();
+
+    if (watch_id != (guint) -1)
+        g_source_remove(watch_id);
     
+    if (io)
+        g_io_channel_unref(io);
+
+        
     if (loop)
         g_main_loop_unref(loop);
 
     if (r != 0 && config->daemonize)
-        daemon_retval_send(0);
+        daemon_retval_send(1);
     
     return r;
 }
@@ -348,7 +436,7 @@ int main(int argc, char *argv[]) {
 
     } else if (config.command == DAEMON_KILL) {
         if (daemon_pid_file_kill_wait(SIGTERM, 5) < 0) {
-            avahi_log_warn("Failed to kill daemon");
+            avahi_log_warn("Failed to kill daemon: %s", strerror(errno));
             goto finish;
         }
 
@@ -385,8 +473,10 @@ int main(int argc, char *argv[]) {
         }
 
         if (daemon_pid_file_create() < 0) {
-            avahi_log_error("Failed to create PID file.");
-            daemon_retval_send(1);
+            avahi_log_error("Failed to create PID file: %s", strerror(errno));
+
+            if (config.daemonize)
+                daemon_retval_send(1);
             goto finish;
         } else
             wrote_pid_file = TRUE;
index 91a8287e667ff833cc8702c09eb4a62a57a7d548..6eaef999268aa3e282cf77c594e7a4c5ad680c46 100644 (file)
@@ -34,6 +34,7 @@
 #include <glib.h>
 
 #include <avahi-core/llist.h>
+#include <avahi-core/log.h>
 
 #include "simple-protocol.h"
 #include "main.h"
@@ -80,6 +81,7 @@ struct Server {
     AVAHI_LLIST_HEAD(Client, clients);
 
     guint n_clients;
+    gboolean bind_successful;
 };
 
 static Server *server = NULL;
@@ -264,7 +266,7 @@ static void client_work(Client *c) {
         
         if ((r = read(c->fd, c->inbuf + c->inbuf_length, sizeof(c->inbuf) - c->inbuf_length)) <= 0) {
             if (r < 0)
-                g_warning("read(): %s", strerror(errno));
+                avahi_log_warn("read(): %s", strerror(errno));
             client_free(c);
             return;
         }
@@ -279,7 +281,7 @@ static void client_work(Client *c) {
         ssize_t r;
 
         if ((r = write(c->fd, c->outbuf, c->outbuf_length)) < 0) {
-            g_warning("write(): %s", strerror(errno));
+            avahi_log_warn("write(): %s", strerror(errno));
             client_free(c);
             return;
         }
@@ -337,7 +339,7 @@ static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer us
         gint fd;
 
         if ((fd = accept(s->fd, NULL, NULL)) < 0)
-            g_warning("accept(): %s", strerror(errno));
+            avahi_log_warn("accept(): %s", strerror(errno));
         else
             client_new(s, fd);
     } else if (s->poll_fd.revents)
@@ -368,23 +370,21 @@ int simple_protocol_setup(GMainContext *c) {
     g_assert(!server);
 
     server = (Server*) g_source_new(&source_funcs, sizeof(Server));
+    server->bind_successful = FALSE;
     server->fd = -1;
     AVAHI_LLIST_HEAD_INIT(Client, server->clients);
-    if (c)
-        g_main_context_ref(server->context = c);
-    else
-        server->context = g_main_context_default();
+    g_main_context_ref(server->context = (c ? c : g_main_context_default()));
     server->clients = NULL;
 
     u = umask(0000);
 
     if (mkdir(UNIX_SOCKET_PATH, 0755) < 0 && errno != EEXIST) {
-        g_warning("mkdir(): %s", strerror(errno));
+        avahi_log_warn("mkdir(): %s", strerror(errno));
         goto fail;
     }
     
     if ((server->fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) {
-        g_warning("socket(PF_LOCAL, SOCK_STREAM, 0): %s", strerror(errno));
+        avahi_log_warn("socket(PF_LOCAL, SOCK_STREAM, 0): %s", strerror(errno));
         goto fail;
     }
 
@@ -393,12 +393,14 @@ int simple_protocol_setup(GMainContext *c) {
     strncpy(sa.sun_path, UNIX_SOCKET, sizeof(sa.sun_path)-1);
 
     if (bind(server->fd, &sa, sizeof(sa)) < 0) {
-        g_warning("bind(): %s", strerror(errno));
+        avahi_log_warn("bind(): %s", strerror(errno));
         goto fail;
     }
+
+    server->bind_successful = TRUE;
     
     if (listen(server->fd, 2) < 0) {
-        g_warning("listen(): %s", strerror(errno));
+        avahi_log_warn("listen(): %s", strerror(errno));
         goto fail;
     }
 
@@ -427,13 +429,15 @@ void simple_protocol_shutdown(void) {
 
         while (server->clients)
             client_free(server->clients);
+
+        if (server->bind_successful)
+            unlink(UNIX_SOCKET);
         
-        if (server->fd >= 0) {
-            unlink(UNIX_SOCKET_PATH);
+        if (server->fd >= 0)
             close(server->fd);
-        }
 
         g_main_context_unref(server->context);
+        
         g_source_destroy(&server->source);
         g_source_unref(&server->source);
 
index 89e81227e03de549034cacf13587ea868a31de8d..8148de451fa2a6e3391c96514092f1109c27ca27 100644 (file)
@@ -211,7 +211,7 @@ static void add_static_service_group_to_server(StaticServiceGroup *g) {
                 -1, AF_UNSPEC,
                 s->type, g->chosen_name,
                 s->domain_name, s->host_name, s->port,
-                s->txt_records) < 0) {
+                avahi_string_list_copy(s->txt_records)) < 0) {
             g_message("Failed to add service '%s' of type '%s', ignoring service group (%s)", g->chosen_name, s->type, g->filename);
             remove_static_service_group_from_server(g);
             return;