diff options
Diffstat (limited to 'bus')
-rw-r--r-- | bus/bus.c | 47 | ||||
-rw-r--r-- | bus/config-parser.c | 47 | ||||
-rw-r--r-- | bus/config-parser.h | 1 | ||||
-rwxr-xr-x | bus/messagebus.in | 12 | ||||
-rw-r--r-- | bus/system.conf.in | 5 |
5 files changed, 105 insertions, 7 deletions
@@ -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 --> |