summaryrefslogtreecommitdiffstats
path: root/bus
diff options
context:
space:
mode:
Diffstat (limited to 'bus')
-rw-r--r--bus/bus.c47
-rw-r--r--bus/config-parser.c47
-rw-r--r--bus/config-parser.h1
-rwxr-xr-xbus/messagebus.in12
-rw-r--r--bus/system.conf.in5
5 files changed, 105 insertions, 7 deletions
diff --git a/bus/bus.c b/bus/bus.c
index 880f35d1..09a0b5bb 100644
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -306,7 +306,7 @@ bus_context_new (const DBusString *config_file,
DBusList **addresses;
BusConfigParser *parser;
DBusString full_address;
- const char *user;
+ const char *user, *pidfile;
char **auth_mechanisms;
DBusList **auth_mechanisms_list;
int len;
@@ -333,6 +333,31 @@ bus_context_new (const DBusString *config_file,
parser = bus_config_load (config_file, error);
if (parser == NULL)
goto failed;
+
+ /* Check for an existing pid file. Of course this is a race;
+ * we'd have to use fcntl() locks on the pid file to
+ * avoid that. But we want to check for the pid file
+ * before overwriting any existing sockets, etc.
+ */
+ pidfile = bus_config_parser_get_pidfile (parser);
+ if (pidfile != NULL)
+ {
+ DBusString u;
+ DBusStat stbuf;
+ DBusError tmp_error;
+
+ dbus_error_init (&tmp_error);
+ _dbus_string_init_const (&u, pidfile);
+
+ if (_dbus_stat (&u, &stbuf, &tmp_error))
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "The pid file \"%s\" exists, if the message bus is not running, remove this file",
+ pidfile);
+ dbus_error_free (&tmp_error);
+ goto failed;
+ }
+ }
context = dbus_new0 (BusContext, 1);
if (context == NULL)
@@ -587,9 +612,27 @@ bus_context_new (const DBusString *config_file,
/* Now become a daemon if appropriate */
if (bus_config_parser_get_fork (parser))
{
- if (!_dbus_become_daemon (error))
+ DBusString u;
+
+ if (pidfile)
+ _dbus_string_init_const (&u, pidfile);
+
+ if (!_dbus_become_daemon (pidfile ? &u : NULL, error))
goto failed;
}
+ else
+ {
+ /* Need to write PID file for ourselves, not for the child process */
+ if (pidfile != NULL)
+ {
+ DBusString u;
+
+ _dbus_string_init_const (&u, pidfile);
+
+ if (!_dbus_write_pid_file (&u, _dbus_getpid (), error))
+ goto failed;
+ }
+ }
bus_config_parser_unref (parser);
_dbus_string_free (&full_address);
diff --git a/bus/config-parser.c b/bus/config-parser.c
index f9473ff9..1052dc2d 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -40,6 +40,7 @@ typedef enum
ELEMENT_ALLOW,
ELEMENT_DENY,
ELEMENT_FORK,
+ ELEMENT_PIDFILE,
ELEMENT_SERVICEDIR,
ELEMENT_INCLUDEDIR,
ELEMENT_TYPE
@@ -94,6 +95,8 @@ struct BusConfigParser
DBusList *service_dirs; /**< Directories to look for services in */
unsigned int fork : 1; /**< TRUE to fork into daemon mode */
+
+ char *pidfile;
};
static const char*
@@ -123,6 +126,8 @@ element_type_to_name (ElementType type)
return "deny";
case ELEMENT_FORK:
return "fork";
+ case ELEMENT_PIDFILE:
+ return "pidfile";
case ELEMENT_SERVICEDIR:
return "servicedir";
case ELEMENT_INCLUDEDIR:
@@ -222,6 +227,13 @@ merge_included (BusConfigParser *parser,
if (included->fork)
parser->fork = TRUE;
+
+ if (included->pidfile != NULL)
+ {
+ dbus_free (parser->pidfile);
+ parser->pidfile = included->pidfile;
+ included->pidfile = NULL;
+ }
while ((link = _dbus_list_pop_first_link (&included->listen_on)))
_dbus_list_append_link (&parser->listen_on, link);
@@ -284,6 +296,7 @@ bus_config_parser_unref (BusConfigParser *parser)
dbus_free (parser->user);
dbus_free (parser->bus_type);
+ dbus_free (parser->pidfile);
_dbus_list_foreach (&parser->listen_on,
(DBusForeachFunction) dbus_free,
@@ -499,6 +512,19 @@ start_busconfig_child (BusConfigParser *parser,
return TRUE;
}
+ else if (strcmp (element_name, "pidfile") == 0)
+ {
+ if (!check_no_attributes (parser, "pidfile", attribute_names, attribute_values, error))
+ return FALSE;
+
+ if (push_element (parser, ELEMENT_PIDFILE) == NULL)
+ {
+ BUS_SET_OOM (error);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
else if (strcmp (element_name, "listen") == 0)
{
if (!check_no_attributes (parser, "listen", attribute_names, attribute_values, error))
@@ -770,6 +796,7 @@ bus_config_parser_end_element (BusConfigParser *parser,
case ELEMENT_USER:
case ELEMENT_TYPE:
case ELEMENT_LISTEN:
+ case ELEMENT_PIDFILE:
case ELEMENT_AUTH:
case ELEMENT_SERVICEDIR:
case ELEMENT_INCLUDEDIR:
@@ -1004,6 +1031,20 @@ bus_config_parser_content (BusConfigParser *parser,
return FALSE;
}
+ case ELEMENT_PIDFILE:
+ {
+ char *s;
+
+ e->had_content = TRUE;
+
+ if (!_dbus_string_copy_data (content, &s))
+ goto nomem;
+
+ dbus_free (parser->pidfile);
+ parser->pidfile = s;
+ }
+ break;
+
case ELEMENT_INCLUDE:
{
DBusString full_path;
@@ -1222,6 +1263,12 @@ bus_config_parser_get_fork (BusConfigParser *parser)
return parser->fork;
}
+const char *
+bus_config_parser_get_pidfile (BusConfigParser *parser)
+{
+ return parser->pidfile;
+}
+
#ifdef DBUS_BUILD_TESTS
#include <stdio.h>
diff --git a/bus/config-parser.h b/bus/config-parser.h
index af5c8260..93d41003 100644
--- a/bus/config-parser.h
+++ b/bus/config-parser.h
@@ -60,6 +60,7 @@ const char* bus_config_parser_get_type (BusConfigParser *parser);
DBusList** bus_config_parser_get_addresses (BusConfigParser *parser);
DBusList** bus_config_parser_get_mechanisms (BusConfigParser *parser);
dbus_bool_t bus_config_parser_get_fork (BusConfigParser *parser);
+const char* bus_config_parser_get_pidfile (BusConfigParser *parser);
DBusList** bus_config_parser_get_service_dirs (BusConfigParser *parser);
/* Loader functions (backended off one of the XML parsers). Returns a
diff --git a/bus/messagebus.in b/bus/messagebus.in
index 60c70777..45388a5e 100755
--- a/bus/messagebus.in
+++ b/bus/messagebus.in
@@ -7,7 +7,7 @@
# and other messages. See http://www.freedesktop.org/software/dbus/
#
# processname: dbus-daemon-1
-# pidfile: @EXPANDED_LOCALSTATEDIR@/messagebus.pid
+# pidfile: @DBUS_SYSTEM_PID_FILE@
#
# Sanity checks.
@@ -20,7 +20,7 @@ RETVAL=0
start() {
echo -n $"Starting system message bus: "
- daemon dbus-daemon-1 --system
+ daemon --check messagebus dbus-daemon-1 --system
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch @EXPANDED_LOCALSTATEDIR@/lock/subsys/messagebus
@@ -28,7 +28,11 @@ start() {
stop() {
echo -n $"Stopping system message bus: "
- killproc messagebus
+
+ ## we don't want to kill all the per-user dbus-daemon-1, we want
+ ## to use the pid file *only*; because we use the fake nonexistent
+ ## program name "messagebus" that should be safe-ish
+ killproc messagebus -TERM
RETVAL=$?
echo
if [ $RETVAL -eq 0 ]; then
@@ -59,7 +63,7 @@ case "$1" in
fi
;;
reload)
- killproc messagebus -HUP
+ echo "Message bus can't reload its configuration, you have to restart it"
RETVAL=$?
;;
*)
diff --git a/bus/system.conf.in b/bus/system.conf.in
index 15a4972e..0e570575 100644
--- a/bus/system.conf.in
+++ b/bus/system.conf.in
@@ -20,11 +20,14 @@
<!-- Fork into daemon mode -->
<fork/>
+ <!-- Write a pid file -->
+ <pidfile>@DBUS_SYSTEM_PID_FILE@</pidfile>
+
<!-- Only allow socket-credentials-based authentication -->
<auth>EXTERNAL</auth>
<!-- Only listen on a local socket -->
- <listen>unix:path=@EXPANDED_LOCALSTATEDIR@/@DBUS_SYSTEM_SOCKET@</listen>
+ <listen>unix:path=@DBUS_SYSTEM_SOCKET@</listen>
<policy context="default">
<!-- Deny everything then punch holes -->