summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-04-06 18:03:03 +0000
committerHavoc Pennington <hp@redhat.com>2003-04-06 18:03:03 +0000
commite45e4382274149ca60c11f068ccca719f3598074 (patch)
tree5fda8d67759828cd7b8e2f1c9a8f4d66f63b737f
parent2618e1a973b816ab59422035046111360ab5aa74 (diff)
2003-04-06 Havoc Pennington <hp@pobox.com>
* bus/bus.c (bus_context_new): fix wrong handling of server_data_slot_unref() in the error case. * dbus/dbus-internals.h (_dbus_assert): change so it passes "(condition) != 0" to _dbus_real_assert so that "_dbus_assert (pointer)" doesn't cause a warning * bus/main.c (main): accept --print-address option to print out the message bus address * dbus/dbus-sysdeps.c (_dbus_generate_random_ascii): export this * dbus/dbus-transport.c (_dbus_transport_open): special error for "tmpdir" option to unix: address on client side * dbus/dbus-server.c (dbus_server_listen): handle "tmpdir" option to unix: address * configure.in (TEST_SOCKET_DIR): locate a temporary directory we can use to create sockets in the test suite. * bus/main.c (signal_handler): on SIGTERM, exit the daemon cleanly. To be used for testing. * dbus/dbus-spawn.c (babysit): use _dbus_set_signal_handler() * dbus/dbus-sysdeps.c (_dbus_set_signal_handler): new * dbus/dbus-server-debug-pipe.c (_dbus_transport_debug_pipe_new): handle trying to call this when there's no servers active
-rw-r--r--ChangeLog33
-rw-r--r--bus/bus.c20
-rw-r--r--bus/bus.h1
-rw-r--r--bus/main.c134
-rw-r--r--bus/session.conf.in14
-rw-r--r--configure.in68
-rw-r--r--dbus/dbus-errors.c2
-rw-r--r--dbus/dbus-internals.h4
-rw-r--r--dbus/dbus-server-debug-pipe.c8
-rw-r--r--dbus/dbus-server.c73
-rw-r--r--dbus/dbus-spawn.c12
-rw-r--r--dbus/dbus-sysdeps.c186
-rw-r--r--dbus/dbus-sysdeps.h8
-rw-r--r--dbus/dbus-transport.c11
14 files changed, 439 insertions, 135 deletions
diff --git a/ChangeLog b/ChangeLog
index ebb48867..ef4c1555 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2003-04-06 Havoc Pennington <hp@pobox.com>
+
+ * bus/bus.c (bus_context_new): fix wrong handling of
+ server_data_slot_unref() in the error case.
+
+ * dbus/dbus-internals.h (_dbus_assert): change so it passes
+ "(condition) != 0" to _dbus_real_assert so that
+ "_dbus_assert (pointer)" doesn't cause a warning
+
+ * bus/main.c (main): accept --print-address option to print out
+ the message bus address
+
+ * dbus/dbus-sysdeps.c (_dbus_generate_random_ascii): export this
+
+ * dbus/dbus-transport.c (_dbus_transport_open): special error for
+ "tmpdir" option to unix: address on client side
+
+ * dbus/dbus-server.c (dbus_server_listen): handle "tmpdir" option
+ to unix: address
+
+ * configure.in (TEST_SOCKET_DIR): locate a temporary directory
+ we can use to create sockets in the test suite.
+
+ * bus/main.c (signal_handler): on SIGTERM, exit the daemon
+ cleanly. To be used for testing.
+
+ * dbus/dbus-spawn.c (babysit): use _dbus_set_signal_handler()
+
+ * dbus/dbus-sysdeps.c (_dbus_set_signal_handler): new
+
+ * dbus/dbus-server-debug-pipe.c (_dbus_transport_debug_pipe_new):
+ handle trying to call this when there's no servers active
+
2003-04-05 Havoc Pennington <hp@pobox.com>
* NEWS: update
diff --git a/bus/bus.c b/bus/bus.c
index 6c5a3f28..e426706a 100644
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -107,7 +107,10 @@ server_get_context (DBusServer *server)
bd = BUS_SERVER_DATA (server);
if (bd == NULL)
- return NULL;
+ {
+ server_data_slot_unref ();
+ return NULL;
+ }
context = bd->context;
@@ -314,7 +317,7 @@ bus_context_new (const DBusString *config_file,
BUS_SET_OOM (error);
return NULL;
}
-
+
if (!server_data_slot_ref ())
{
BUS_SET_OOM (error);
@@ -339,6 +342,12 @@ bus_context_new (const DBusString *config_file,
context->refcount = 1;
+ /* we need another ref of the server data slot for the context
+ * to own
+ */
+ if (!server_data_slot_ref ())
+ _dbus_assert_not_reached ("second ref of server data slot failed");
+
#ifdef DBUS_BUILD_TESTS
context->activation_timeout = 6000; /* 6 seconds */
#else
@@ -542,6 +551,7 @@ bus_context_new (const DBusString *config_file,
bus_config_parser_unref (parser);
_dbus_string_free (&full_address);
dbus_free_string_array (auth_mechanisms);
+ server_data_slot_unref ();
return context;
@@ -678,6 +688,12 @@ bus_context_get_type (BusContext *context)
return context->type;
}
+const char*
+bus_context_get_address (BusContext *context)
+{
+ return context->address;
+}
+
BusRegistry*
bus_context_get_registry (BusContext *context)
{
diff --git a/bus/bus.h b/bus/bus.h
index 8b26cffc..aa9f848d 100644
--- a/bus/bus.h
+++ b/bus/bus.h
@@ -46,6 +46,7 @@ void bus_context_shutdown (BusContext *context)
void bus_context_ref (BusContext *context);
void bus_context_unref (BusContext *context);
const char* bus_context_get_type (BusContext *context);
+const char* bus_context_get_address (BusContext *context);
BusRegistry* bus_context_get_registry (BusContext *context);
BusConnections* bus_context_get_connections (BusContext *context);
BusActivation* bus_context_get_activation (BusContext *context);
diff --git a/bus/main.c b/bus/main.c
index 099219c3..119520ff 100644
--- a/bus/main.c
+++ b/bus/main.c
@@ -26,11 +26,29 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <signal.h>
+#include <errno.h>
+
+static BusContext *context;
+static dbus_bool_t got_sighup = FALSE;
+
+static void
+signal_handler (int sig)
+{
+ switch (sig)
+ {
+ case SIGHUP:
+ got_sighup = TRUE;
+ case SIGTERM:
+ bus_loop_quit (bus_context_get_loop (context));
+ break;
+ }
+}
static void
usage (void)
{
- fprintf (stderr, "dbus-daemon-1 [--session] [--system] [--config-file=FILE] [--version]\n");
+ fprintf (stderr, "dbus-daemon-1 [--version] [--session] [--system] [--config-file=FILE] [--print-address[=descriptor]]\n");
exit (1);
}
@@ -57,17 +75,36 @@ check_two_config_files (const DBusString *config_file,
}
}
+static void
+check_two_addr_descriptors (const DBusString *addr_fd,
+ const char *extra_arg)
+{
+ if (_dbus_string_get_length (addr_fd) > 0)
+ {
+ fprintf (stderr, "--%s specified but printing address to %s already requested\n",
+ extra_arg, _dbus_string_get_const_data (addr_fd));
+ exit (1);
+ }
+}
+
int
main (int argc, char **argv)
{
- BusContext *context;
DBusError error;
DBusString config_file;
+ DBusString addr_fd;
const char *prev_arg;
+ int print_addr_fd;
int i;
-
+ dbus_bool_t print_address;
+
if (!_dbus_string_init (&config_file))
return 1;
+
+ if (!_dbus_string_init (&addr_fd))
+ return 1;
+
+ print_address = FALSE;
prev_arg = NULL;
i = 1;
@@ -117,6 +154,32 @@ main (int argc, char **argv)
}
else if (strcmp (arg, "--config-file") == 0)
; /* wait for next arg */
+ else if (strstr (arg, "--print-address=") == arg)
+ {
+ const char *desc;
+
+ check_two_addr_descriptors (&addr_fd, "print-address");
+
+ desc = strchr (arg, '=');
+ ++desc;
+
+ if (!_dbus_string_append (&addr_fd, desc))
+ exit (1);
+
+ print_address = TRUE;
+ }
+ else if (prev_arg &&
+ strcmp (prev_arg, "--print-address") == 0)
+ {
+ check_two_addr_descriptors (&addr_fd, "print-address");
+
+ if (!_dbus_string_append (&addr_fd, arg))
+ exit (1);
+
+ print_address = TRUE;
+ }
+ else if (strcmp (arg, "--print-address") == 0)
+ print_address = TRUE; /* and we'll get the next arg if appropriate */
else
usage ();
@@ -130,6 +193,27 @@ main (int argc, char **argv)
fprintf (stderr, "No configuration file specified.\n");
usage ();
}
+
+ print_addr_fd = -1;
+ if (print_address)
+ {
+ print_addr_fd = 1; /* stdout */
+ if (_dbus_string_get_length (&addr_fd) > 0)
+ {
+ long val;
+ int end;
+ if (!_dbus_string_parse_int (&addr_fd, 0, &val, &end) ||
+ end != _dbus_string_get_length (&addr_fd) ||
+ val < 0 || val > _DBUS_INT_MAX)
+ {
+ fprintf (stderr, "Invalid file descriptor: \"%s\"\n",
+ _dbus_string_get_const_data (&addr_fd));
+ exit (1);
+ }
+
+ print_addr_fd = val;
+ }
+ }
dbus_error_init (&error);
context = bus_context_new (&config_file, &error);
@@ -139,14 +223,56 @@ main (int argc, char **argv)
_dbus_warn ("Failed to start message bus: %s\n",
error.message);
dbus_error_free (&error);
- return 1;
+ exit (1);
}
+
+ /* Note that we don't know whether the print_addr_fd is
+ * one of the sockets we're using to listen on, or some
+ * other random thing. But I think the answer is "don't do
+ * that then"
+ */
+ if (print_addr_fd >= 0)
+ {
+ DBusString addr;
+ const char *a = bus_context_get_address (context);
+ int bytes;
+
+ _dbus_assert (a != NULL);
+ if (!_dbus_string_init (&addr) ||
+ !_dbus_string_append (&addr, a) ||
+ !_dbus_string_append (&addr, "\n"))
+ exit (1);
+
+ bytes = _dbus_string_get_length (&addr);
+ if (_dbus_write (print_addr_fd, &addr, 0, bytes) != bytes)
+ {
+ _dbus_warn ("Failed to print message bus address: %s\n",
+ _dbus_strerror (errno));
+ exit (1);
+ }
+
+ if (print_addr_fd > 2)
+ _dbus_close (print_addr_fd, NULL);
+
+ _dbus_string_free (&addr);
+ }
+
+ /* FIXME we have to handle this properly below _dbus_set_signal_handler (SIGHUP, signal_handler); */
+ _dbus_set_signal_handler (SIGTERM, signal_handler);
_dbus_verbose ("We are on D-Bus...\n");
bus_loop_run (bus_context_get_loop (context));
bus_context_shutdown (context);
bus_context_unref (context);
+
+ /* If we exited on TERM we just exit, if we exited on
+ * HUP we restart the daemon.
+ */
+ if (got_sighup)
+ {
+ /* FIXME execv (argv) basically */
+ }
return 0;
}
diff --git a/bus/session.conf.in b/bus/session.conf.in
index 28478955..d430d990 100644
--- a/bus/session.conf.in
+++ b/bus/session.conf.in
@@ -8,19 +8,7 @@
<!-- Our well-known bus type, don't change this -->
<type>session</type>
- <!-- FIXME - this is fairly complicated to fix.
- Propose the following:
- - add "unix:tmpdir=/tmp" which means unix domain transport
- creates a socket with a random secure name
- - add dbus_server_get_address() that gets the actual
- server address
- - add command line option or env variable to the daemon
- causing it to print its list of addresses to a given
- file descriptor
- - session manager or whatever launches the session bus
- reads the address from there and sets the env variable
- -->
- <listen>unix:path=/tmp/foobar</listen>
+ <listen>unix:tmpdir=@DBUS_SESSION_SOCKET_DIR@</listen>
<policy context="default">
<!-- Allow everything -->
diff --git a/configure.in b/configure.in
index 27483570..d37a7c4b 100644
--- a/configure.in
+++ b/configure.in
@@ -31,8 +31,10 @@ AC_ARG_ENABLE(verbose-mode, [ --enable-verbose-mode support verbose debug mode]
AC_ARG_ENABLE(asserts, [ --enable-asserts include assertion checks],enable_asserts=$enableval,enable_asserts=yes)
AC_ARG_ENABLE(gcov, [ --enable-gcov compile with coverage profiling instrumentation (gcc only)],enable_gcov=$enableval,enable_gcov=no)
-AC_ARG_WITH(xml, [ --with-xml=[libxml/expat] XML library to use])
-AC_ARG_WITH(init-scripts, [ --with-init-scripts=[redhat] Style of init scripts to install])
+AC_ARG_WITH(xml, [ --with-xml=[libxml/expat] XML library to use])
+AC_ARG_WITH(init-scripts, [ --with-init-scripts=[redhat] Style of init scripts to install])
+AC_ARG_WITH(session-socket-dir, [ --with-session-socket-dir=[dirname] Where to put sockets for the per-login-session message bus])
+AC_ARG_WITH(test-socket-dir, [ --with-test-socket-dir=[dirname] Where to put sockets for make check])
dnl DBUS_BUILD_TESTS controls unit tests built in to .c files
dnl and also some stuff in the test/ subdir
@@ -123,6 +125,9 @@ else
fi
fi
+# compress spaces in cflags
+CFLAGS=`echo "$CFLAGS" | sed -e 's/ +/ /g'`
+
if test x$enable_gcov = xyes; then
## so that config.h changes when you toggle gcov support
AC_DEFINE_UNQUOTED(DBUS_GCOV_ENABLED, 1, [Defined if gcov is enabled to force a rebuild due to config.h changing])
@@ -160,6 +165,7 @@ AC_DEFINE_UNQUOTED(DBUS_INT64_TYPE, $dbusint64, [64-bit integer type])
## byte order
AC_C_BIGENDIAN
+#### Various functions
AC_CHECK_LIB(socket,socket)
AC_CHECK_LIB(nsl,gethostbyname)
@@ -443,6 +449,32 @@ TEST_PATH(EXIT_BINARY, test-exit)
TEST_PATH(SEGFAULT_BINARY, test-segfault)
TEST_PATH(SLEEP_FOREVER_BINARY, test-sleep-forever)
+#### Find socket directories
+if ! test -z "$TMPDIR" ; then
+ DEFAULT_SOCKET_DIR=$TMPDIR
+elif ! test -z "$TEMP" ; then
+ DEFAULT_SOCKET_DIR=$TEMP
+elif ! test -z "$TMP" ; then
+ DEFAULT_SOCKET_DIR=$TMP
+else
+ DEFAULT_SOCKET_DIR=/tmp
+fi
+
+if ! test -z "$with_test_socket_dir" ; then
+ TEST_SOCKET_DIR="$with_test_socket_dir"
+else
+ TEST_SOCKET_DIR=$DEFAULT_SOCKET_DIR
+fi
+AC_SUBST(TEST_SOCKET_DIR)
+
+if ! test -z "$with_session_socket_dir" ; then
+ DBUS_SESSION_SOCKET_DIR="$with_session_socket_dir"
+else
+ DBUS_SESSION_SOCKET_DIR=$DEFAULT_SOCKET_DIR
+fi
+AC_SUBST(DBUS_SESSION_SOCKET_DIR)
+
+
AC_OUTPUT([
Doxyfile
bus/system.conf
@@ -466,21 +498,23 @@ echo "
D-BUS $VERSION
==============
- prefix: ${prefix}
- source code location: ${srcdir}
- compiler: ${CC}
- cflags: ${CFLAGS}
-
- Maintainer mode: ${USE_MAINTAINER_MODE}
- gcc coverage profiling: ${enable_gcov}
- Building unit tests: ${enable_tests}
- Building verbose mode: ${enable_verbose_mode}
- Building assertions: ${enable_asserts}
- Building Qt bindings: ${have_qt}
- Building GLib bindings: ${have_glib}
- Using XML parser: ${with_xml}
- System bus socket: ${EXPANDED_LOCALSTATEDIR}/${DBUS_SYSTEM_SOCKET}
- Init scripts style: ${with_init_scripts}
+ prefix: ${prefix}
+ source code location: ${srcdir}
+ compiler: ${CC}
+ cflags: ${CFLAGS}
+
+ Maintainer mode: ${USE_MAINTAINER_MODE}
+ gcc coverage profiling: ${enable_gcov}
+ Building unit tests: ${enable_tests}
+ Building verbose mode: ${enable_verbose_mode}
+ Building assertions: ${enable_asserts}
+ Building Qt bindings: ${have_qt}
+ Building GLib bindings: ${have_glib}
+ Using XML parser: ${with_xml}
+ Init scripts style: ${with_init_scripts}
+ System bus socket: ${EXPANDED_LOCALSTATEDIR}/${DBUS_SYSTEM_SOCKET}
+ Session bus socket dir: ${DBUS_SESSION_SOCKET_DIR}
+ 'make check' socket dir: ${TEST_SOCKET_DIR}
"
if test x$enable_tests = xyes; then
diff --git a/dbus/dbus-errors.c b/dbus/dbus-errors.c
index 7e3aa69b..0f70bcb1 100644
--- a/dbus/dbus-errors.c
+++ b/dbus/dbus-errors.c
@@ -93,7 +93,7 @@ message_from_error (const char *error)
else if (strcmp (error, DBUS_ERROR_AUTH_FAILED) == 0)
return "Could not authenticate to server";
else if (strcmp (error, DBUS_ERROR_NO_SERVER) == 0)
- return "No server";
+ return "No server available at address";
else if (strcmp (error, DBUS_ERROR_TIMEOUT) == 0)
return "Connection timed out";
else if (strcmp (error, DBUS_ERROR_NO_NETWORK) == 0)
diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h
index dbfd0681..f37009b9 100644
--- a/dbus/dbus-internals.h
+++ b/dbus/dbus-internals.h
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-internals.h random utility stuff (internal to D-BUS implementation)
*
- * Copyright (C) 2002 Red Hat, Inc.
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
*
* Licensed under the Academic Free License version 1.2
*
@@ -81,7 +81,7 @@ void _dbus_real_assert (dbus_bool_t condition,
const char *file,
int line);
#define _dbus_assert(condition) \
- _dbus_real_assert ((condition), #condition, __FILE__, __LINE__)
+ _dbus_real_assert ((condition) != 0, #condition, __FILE__, __LINE__)
#endif /* !DBUS_DISABLE_ASSERT */
#ifdef DBUS_DISABLE_ASSERT
diff --git a/dbus/dbus-server-debug-pipe.c b/dbus/dbus-server-debug-pipe.c
index 905349be..151e32b8 100644
--- a/dbus/dbus-server-debug-pipe.c
+++ b/dbus/dbus-server-debug-pipe.c
@@ -220,13 +220,19 @@ _dbus_transport_debug_pipe_new (const char *server_name,
DBusString address;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ if (server_pipe_hash == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL);
+ return NULL;
+ }
server = _dbus_hash_table_lookup_string (server_pipe_hash,
server_name);
if (server == NULL ||
((DBusServerDebugPipe*)server)->disconnected)
{
- dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, NULL);
+ dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL);
return NULL;
}
diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c
index 566e9178..3f877a0f 100644
--- a/dbus/dbus-server.c
+++ b/dbus/dbus-server.c
@@ -305,18 +305,68 @@ dbus_server_listen (const char *address,
if (strcmp (method, "unix") == 0)
{
const char *path = dbus_address_entry_get_value (entries[i], "path");
-
- if (path == NULL)
+ const char *tmpdir = dbus_address_entry_get_value (entries[i], "tmpdir");
+
+ if (path == NULL && tmpdir == NULL)
{
address_problem_type = "unix";
- address_problem_field = "path";
+ address_problem_field = "path or tmpdir";
goto bad_address;
}
- server = _dbus_server_new_for_domain_socket (path, error);
+ if (path && tmpdir)
+ {
+ address_problem_other = "cannot specify both \"path\" and \"tmpdir\" at the same time";
+ goto bad_address;
+ }
- if (server)
- break;
+ if (tmpdir != NULL)
+ {
+ DBusString full_path;
+ DBusString filename;
+
+ if (!_dbus_string_init (&full_path))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+
+ if (!_dbus_string_init (&filename))
+ {
+ _dbus_string_free (&full_path);
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+
+ if (!_dbus_string_append (&filename,
+ "dbus-") ||
+ !_dbus_generate_random_ascii (&filename, 10) ||
+ !_dbus_string_append (&full_path, tmpdir) ||
+ !_dbus_concat_dir_and_file (&full_path, &filename))
+ {
+ _dbus_string_free (&full_path);
+ _dbus_string_free (&filename);
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto out;
+ }
+
+ /* FIXME - we will unconditionally unlink() the path.
+ * unlink() does not follow symlinks, but would like
+ * independent confirmation this is safe enough. See
+ * also _dbus_listen_unix_socket() and comments therein.
+ */
+
+ server =
+ _dbus_server_new_for_domain_socket (_dbus_string_get_const_data (&full_path),
+ error);
+
+ _dbus_string_free (&full_path);
+ _dbus_string_free (&filename);
+ }
+ else
+ {
+ server = _dbus_server_new_for_domain_socket (path, error);
+ }
}
else if (strcmp (method, "tcp") == 0)
{
@@ -361,9 +411,6 @@ dbus_server_listen (const char *address,
}
server = _dbus_server_debug_new (name, error);
-
- if (server)
- break;
}
else if (strcmp (method, "debug-pipe") == 0)
{
@@ -377,9 +424,6 @@ dbus_server_listen (const char *address,
}
server = _dbus_server_debug_pipe_new (name, error);
-
- if (server)
- break;
}
#endif
else
@@ -387,7 +431,12 @@ dbus_server_listen (const char *address,
address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")";
goto bad_address;
}
+
+ if (server)
+ break;
}
+
+ out:
dbus_address_entries_free (entries);
return server;
diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c
index 2273a4e3..87e1ffc2 100644
--- a/dbus/dbus-spawn.c
+++ b/dbus/dbus-spawn.c
@@ -916,9 +916,7 @@ babysit_signal_handler (int signo)
static void
babysit (pid_t grandchild_pid,
int parent_pipe)
-{
- struct sigaction act;
- sigset_t empty_mask;
+{
int sigchld_pipe[2];
/* I thought SIGCHLD would just wake up the poll, but
@@ -933,12 +931,8 @@ babysit (pid_t grandchild_pid,
}
babysit_sigchld_pipe = sigchld_pipe[WRITE_END];
-
- sigemptyset (&empty_mask);
- act.sa_handler = babysit_signal_handler;
- act.sa_mask = empty_mask;
- act.sa_flags = 0;
- sigaction (SIGCHLD, &act, 0);
+
+ _dbus_set_signal_handler (SIGCHLD, babysit_signal_handler);
write_pid (parent_pipe, grandchild_pid);
diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c
index 3588f762..7a389956 100644
--- a/dbus/dbus-sysdeps.c
+++ b/dbus/dbus-sysdeps.c
@@ -2007,36 +2007,6 @@ _dbus_file_get_contents (DBusString *str,
}
}
-static dbus_bool_t
-append_unique_chars (DBusString *str)
-{
- static const char letters[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- int i;
- int len;
-
-#define N_UNIQUE_CHARS 8
-
- if (!_dbus_generate_random_bytes (str, N_UNIQUE_CHARS))
- return FALSE;
-
- len = _dbus_string_get_length (str);
- i = len - N_UNIQUE_CHARS;
- while (i < len)
- {
- _dbus_string_set_byte (str, i,
- letters[_dbus_string_get_byte (str, i) %
- (sizeof (letters) - 1)]);
-
- ++i;
- }
-
- _dbus_assert (_dbus_string_validate_ascii (str, len - N_UNIQUE_CHARS,
- N_UNIQUE_CHARS));
-
- return TRUE;
-}
-
/**
* Writes a string out to a file. If the file exists,
* it will be atomically overwritten by the new data.
@@ -2083,8 +2053,9 @@ _dbus_string_save_to_file (const DBusString *str,
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return FALSE;
}
-
- if (!append_unique_chars (&tmp_filename))
+
+#define N_TMP_FILENAME_RANDOM_BYTES 8
+ if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
return FALSE;
@@ -2487,13 +2458,52 @@ _dbus_directory_close (DBusDirIter *iter)
dbus_free (iter);
}
+static dbus_bool_t
+pseudorandom_generate_random_bytes (DBusString *str,
+ int n_bytes)
+{
+ int old_len;
+ unsigned long tv_usec;
+ int i;
+
+ old_len = _dbus_string_get_length (str);
+
+ /* fall back to pseudorandom */
+ _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
+ n_bytes);
+
+ _dbus_get_current_time (NULL, &tv_usec);
+ srand (tv_usec);
+
+ i = 0;
+ while (i < n_bytes)
+ {
+ double r;
+ unsigned int b;
+
+ r = rand ();
+ b = (r / (double) RAND_MAX) * 255.0;
+
+ if (!_dbus_string_append_byte (str, b))
+ goto failed;
+
+ ++i;
+ }
+
+ return TRUE;
+
+ failed:
+ _dbus_string_set_length (str, old_len);
+ return FALSE;
+}
+
/**
* Generates the given number of random bytes,
* using the best mechanism we can come up with.
*
* @param str the string
* @param n_bytes the number of random bytes to append to string
- * @returns #TRUE on success, #FALSE if no memory or other failure
+ * @returns #TRUE on success, #FALSE if no memory
*/
dbus_bool_t
_dbus_generate_random_bytes (DBusString *str,
@@ -2501,6 +2511,12 @@ _dbus_generate_random_bytes (DBusString *str,
{
int old_len;
int fd;
+
+ /* FALSE return means "no memory", if it could
+ * mean something else then we'd need to return
+ * a DBusError. So we always fall back to pseudorandom
+ * if the I/O fails.
+ */
old_len = _dbus_string_get_length (str);
fd = -1;
@@ -2508,52 +2524,58 @@ _dbus_generate_random_bytes (DBusString *str,
/* note, urandom on linux will fall back to pseudorandom */
fd = open ("/dev/urandom", O_RDONLY);
if (fd < 0)
+ return pseudorandom_generate_random_bytes (str, n_bytes);
+
+ if (_dbus_read (fd, str, n_bytes) != n_bytes)
{
- unsigned long tv_usec;
- int i;
+ close (fd);
+ _dbus_string_set_length (str, old_len);
+ return pseudorandom_generate_random_bytes (str, n_bytes);
+ }
- /* fall back to pseudorandom */
- _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
- n_bytes);
-
- _dbus_get_current_time (NULL, &tv_usec);
- srand (tv_usec);
-
- i = 0;
- while (i < n_bytes)
- {
- double r;
- unsigned int b;
-
- r = rand ();
- b = (r / (double) RAND_MAX) * 255.0;
-
- if (!_dbus_string_append_byte (str, b))
- goto failed;
-
- ++i;
- }
+ _dbus_verbose ("Read %d bytes from /dev/urandom\n",
+ n_bytes);
+
+ close (fd);
+
+ return TRUE;
+}
- return TRUE;
- }
- else
+/**
+ * Generates the given number of random bytes, where the bytes are
+ * chosen from the alphanumeric ASCII subset.
+ *
+ * @param str the string
+ * @param n_bytes the number of random ASCII bytes to append to string
+ * @returns #TRUE on success, #FALSE if no memory or other failure
+ */
+dbus_bool_t
+_dbus_generate_random_ascii (DBusString *str,
+ int n_bytes)
+{
+ static const char letters[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
+ int i;
+ int len;
+
+ if (!_dbus_generate_random_bytes (str, n_bytes))
+ return FALSE;
+
+ len = _dbus_string_get_length (str);
+ i = len - n_bytes;
+ while (i < len)
{
- if (_dbus_read (fd, str, n_bytes) != n_bytes)
- goto failed;
-
- _dbus_verbose ("Read %d bytes from /dev/urandom\n",
- n_bytes);
-
- close (fd);
+ _dbus_string_set_byte (str, i,
+ letters[_dbus_string_get_byte (str, i) %
+ (sizeof (letters) - 1)]);
- return TRUE;
+ ++i;
}
- failed:
- _dbus_string_set_length (str, old_len);
- if (fd >= 0)
- close (fd);
- return FALSE;
+ _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes,
+ n_bytes));
+
+ return TRUE;
}
/**
@@ -3005,6 +3027,26 @@ _dbus_change_identity (unsigned long uid,
return TRUE;
}
+/** Installs a UNIX signal handler
+ *
+ * @param sig the signal to handle
+ * @param handler the handler
+ */
+void
+_dbus_set_signal_handler (int sig,
+ DBusSignalHandler handler)
+{
+ struct sigaction act;
+ sigset_t empty_mask;
+
+ sigemptyset (&empty_mask);
+ act.sa_handler = handler;
+ act.sa_mask = empty_mask;
+ act.sa_flags = 0;
+ sigaction (sig, &act, 0);
+}
+
+
#ifdef DBUS_BUILD_TESTS
#include <stdlib.h>
static void
diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h
index 77d54c8c..933e2775 100644
--- a/dbus/dbus-sysdeps.h
+++ b/dbus/dbus-sysdeps.h
@@ -180,6 +180,8 @@ void _dbus_directory_close (DBusDirIter *iter);
dbus_bool_t _dbus_generate_random_bytes (DBusString *str,
int n_bytes);
+dbus_bool_t _dbus_generate_random_ascii (DBusString *str,
+ int n_bytes);
const char *_dbus_errno_to_string (int errnum);
const char* _dbus_error_from_errno (int error_number);
@@ -220,6 +222,12 @@ dbus_bool_t _dbus_change_identity (unsigned long uid,
unsigned long gid,
DBusError *error);
+typedef void (* DBusSignalHandler) (int sig);
+
+void _dbus_set_signal_handler (int sig,
+ DBusSignalHandler handler);
+
+
DBUS_END_DECLS;
#endif /* DBUS_SYSDEPS_H */
diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c
index e56c8b0c..d074480a 100644
--- a/dbus/dbus-transport.c
+++ b/dbus/dbus-transport.c
@@ -235,7 +235,14 @@ _dbus_transport_open (const char *address,
if (strcmp (method, "unix") == 0)
{
const char *path = dbus_address_entry_get_value (entries[i], "path");
+ const char *tmpdir = dbus_address_entry_get_value (entries[i], "tmpdir");
+ if (tmpdir != NULL)
+ {
+ address_problem_other = "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on";
+ goto bad_address;
+ }
+
if (path == NULL)
{
address_problem_type = "unix";
@@ -243,7 +250,7 @@ _dbus_transport_open (const char *address,
goto bad_address;
}
- transport = _dbus_transport_new_for_domain_socket (path, error);
+ transport = _dbus_transport_new_for_domain_socket (path, error);
}
else if (strcmp (method, "tcp") == 0)
{
@@ -309,7 +316,7 @@ _dbus_transport_open (const char *address,
if (transport)
break;
}
-
+
dbus_address_entries_free (entries);
return transport;