summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2005-06-18 23:22:20 +0000
committerLennart Poettering <lennart@poettering.net>2005-06-18 23:22:20 +0000
commit64ab9be453f31b55e35ad5cad8102a9e45244a8c (patch)
tree406e428023ed2124a776f7a0bdb6719f3ddc0f14
parent768d6a386735d3a0805547a2de728886f2aa8798 (diff)
* fix memory handling when reading configuration files
* 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
-rw-r--r--avahi-core/netlink.c4
-rw-r--r--avahi-core/server.c5
-rw-r--r--avahi-daemon/main.c130
-rw-r--r--avahi-daemon/simple-protocol.c32
-rw-r--r--avahi-daemon/static-services.c2
5 files changed, 131 insertions, 42 deletions
diff --git a/avahi-core/netlink.c b/avahi-core/netlink.c
index 50ddf5c..ff88b91 100644
--- a/avahi-core/netlink.c
+++ b/avahi-core/netlink.c
@@ -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;
diff --git a/avahi-core/server.c b/avahi-core/server.c
index 0c00658..d03a284 100644
--- a/avahi-core/server.c
+++ b/avahi-core/server.c
@@ -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*));
diff --git a/avahi-daemon/main.c b/avahi-daemon/main.c
index 4373f9a..0d862ea 100644
--- a/avahi-daemon/main.c
+++ b/avahi-daemon/main.c
@@ -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;
diff --git a/avahi-daemon/simple-protocol.c b/avahi-daemon/simple-protocol.c
index 91a8287..6eaef99 100644
--- a/avahi-daemon/simple-protocol.c
+++ b/avahi-daemon/simple-protocol.c
@@ -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);
diff --git a/avahi-daemon/static-services.c b/avahi-daemon/static-services.c
index 89e8122..8148de4 100644
--- a/avahi-daemon/static-services.c
+++ b/avahi-daemon/static-services.c
@@ -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;