diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2011-08-05 14:52:37 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2011-08-05 14:52:37 +0100 |
commit | a1c90cacfa6e4e176bffb85a8880dd829f1e3acb (patch) | |
tree | 0f191829bb12a291fe1dfe453180b16f5130210d /bus | |
parent | d6ad37c3044ed6c72bf652c6e505c6ad9aa9e889 (diff) | |
parent | 6c6ae1efcd9c3d2f43bf282d90cfc5f2d7e0b0e7 (diff) | |
download | dbus-a1c90cacfa6e4e176bffb85a8880dd829f1e3acb.tar.gz |
Merge branch 'dbus-1.4'
Conflicts:
bus/main.c
Diffstat (limited to 'bus')
-rw-r--r-- | bus/main.c | 84 |
1 files changed, 75 insertions, 9 deletions
@@ -49,10 +49,15 @@ static int reload_pipe[2]; static void close_reload_pipe (DBusWatch **); #ifdef DBUS_UNIX +typedef enum + { + ACTION_RELOAD = 'r', + ACTION_QUIT = 'q' + } SignalAction; + static void signal_handler (int sig) { - switch (sig) { #ifdef DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX @@ -63,7 +68,9 @@ signal_handler (int sig) case SIGHUP: { DBusString str; - _dbus_string_init_const (&str, "foo"); + char action[2] = { ACTION_RELOAD, '\0' }; + + _dbus_string_init_const (&str, action); if ((reload_pipe[RELOAD_WRITE_END] > 0) && !_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1)) { @@ -88,6 +95,28 @@ signal_handler (int sig) } break; #endif + + case SIGTERM: + { + DBusString str; + char action[2] = { ACTION_QUIT, '\0' }; + _dbus_string_init_const (&str, action); + if ((reload_pipe[RELOAD_WRITE_END] < 0) || + !_dbus_write_socket (reload_pipe[RELOAD_WRITE_END], &str, 0, 1)) + { + /* If we can't write to the socket, dying seems a more + * important response to SIGTERM than cleaning up sockets, + * so we exit. We'd use exit(), but that's not async-signal-safe, + * so we'll have to resort to _exit(). */ + static const char message[] = + "Unable to write termination signal to pipe - buffer full?\n" + "Will exit instead.\n"; + + write (STDERR_FILENO, message, strlen (message)); + _exit (1); + } + } + break; } } #endif /* DBUS_UNIX */ @@ -190,6 +219,8 @@ handle_reload_watch (DBusWatch *watch, { DBusError error; DBusString str; + char *action_str; + char action = '\0'; while (!_dbus_string_init (&str)) _dbus_wait_for_memory (); @@ -201,6 +232,12 @@ handle_reload_watch (DBusWatch *watch, close_reload_pipe (&watch); return TRUE; } + + action_str = _dbus_string_get_data (&str); + if (action_str != NULL) + { + action = action_str[0]; + } _dbus_string_free (&str); /* this can only fail if we don't understand the config file @@ -208,15 +245,42 @@ handle_reload_watch (DBusWatch *watch, * loaded config. */ dbus_error_init (&error); - if (! bus_context_reload_config (context, &error)) + + switch (action) { - _DBUS_ASSERT_ERROR_IS_SET (&error); - _dbus_assert (dbus_error_has_name (&error, DBUS_ERROR_FAILED) || - dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)); - _dbus_warn ("Unable to reload configuration: %s\n", - error.message); - dbus_error_free (&error); + case ACTION_RELOAD: + if (! bus_context_reload_config (context, &error)) + { + _DBUS_ASSERT_ERROR_IS_SET (&error); + _dbus_assert (dbus_error_has_name (&error, DBUS_ERROR_FAILED) || + dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)); + _dbus_warn ("Unable to reload configuration: %s\n", + error.message); + dbus_error_free (&error); + } + break; + + case ACTION_QUIT: + { + DBusLoop *loop; + /* + * On OSs without abstract sockets, we want to quit + * gracefully rather than being killed by SIGTERM, + * so that DBusServer gets a chance to clean up the + * sockets from the filesystem. fd.o #38656 + */ + loop = bus_context_get_loop (context); + if (loop != NULL) + { + _dbus_loop_quit (loop); + } + } + break; + + default: + break; } + return TRUE; } @@ -527,6 +591,8 @@ main (int argc, char **argv) /* POSIX signals are Unix-specific, and _dbus_set_signal_handler is * unimplemented (and probably unimplementable) on Windows, so there's * no point in trying to make the handler portable to non-Unix. */ + + _dbus_set_signal_handler (SIGTERM, signal_handler); #ifdef SIGHUP _dbus_set_signal_handler (SIGHUP, signal_handler); #endif |