summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-server.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2006-09-16 17:38:24 +0000
committerHavoc Pennington <hp@redhat.com>2006-09-16 17:38:24 +0000
commit8027efc97b4bec85f674570f878919cb72456745 (patch)
tree441ffafa5367bdb93c8bfa7f8ec51acfeb432b0b /dbus/dbus-server.c
parenta0a12210e1f5aa5bd185a57d4394b8eb51cbe472 (diff)
voc Pennington <hp@redhat.com>
* dbus/dbus-server.c (dbus_server_listen): change how this works to be able to delegate to a set of handlers that can succeed, fail, or choose not to handle. Allows us to have dbus_server_listen_platform_specific. * dbus/dbus-server-socket.c (_dbus_server_new_for_tcp_socket): factor out the tcp socket stuff to be used on windows, leaving unix domain socket only in dbus-socket-unix.c * dbus/dbus-transport-socket.c (_dbus_transport_new_for_tcp_socket): factor out the tcp socket stuff to be used on windows, leaving unix domain socket only in dbus-transport-unix.c * dbus/dbus-connection.c (dbus_connection_get_unix_user): insert temporary hack to be sure this fails on windows (dbus_connection_get_unix_process_id): ditto
Diffstat (limited to 'dbus/dbus-server.c')
-rw-r--r--dbus/dbus-server.c271
1 files changed, 129 insertions, 142 deletions
diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c
index 5e980cbd..7a140fd3 100644
--- a/dbus/dbus-server.c
+++ b/dbus/dbus-server.c
@@ -23,6 +23,7 @@
#include "dbus-server.h"
#include "dbus-server-unix.h"
+#include "dbus-server-socket.h"
#include "dbus-string.h"
#ifdef DBUS_BUILD_TESTS
#include "dbus-server-debug-pipe.h"
@@ -441,6 +442,21 @@ _dbus_server_toggle_timeout (DBusServer *server,
enabled);
}
+void
+_dbus_server_set_bad_address (DBusError *error,
+ const char *address_problem_type,
+ const char *address_problem_field,
+ const char *address_problem_other)
+{
+ if (address_problem_type != NULL)
+ dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
+ "Server address of type %s was missing argument %s",
+ address_problem_type, address_problem_field);
+ else
+ dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
+ "Could not parse server address: %s",
+ address_problem_other);
+}
/** @} */
@@ -463,6 +479,18 @@ _dbus_server_toggle_timeout (DBusServer *server,
*
*/
+static const struct {
+ DBusServerListenResult (* func) (DBusAddressEntry *entry,
+ DBusServer **server_p,
+ DBusError *error);
+} listen_funcs[] = {
+ { _dbus_server_listen_socket },
+ { _dbus_server_listen_platform_specific }
+#ifdef DBUS_BUILD_TESTS
+ , { _dbus_server_listen_debug_pipe }
+#endif
+};
+
/**
* Listens for new connections on the given address.
* Returns #NULL if listening fails for any reason.
@@ -470,10 +498,7 @@ _dbus_server_toggle_timeout (DBusServer *server,
* dbus_server_set_new_connection_function() and
* dbus_server_set_watch_functions() should be called
* immediately to render the server fully functional.
- *
- * @todo error messages on bad address could really be better.
- * DBusResultCode is a bit limiting here.
- *
+ *
* @param address the address of this server.
* @param error location to store rationale for failure.
* @returns a new DBusServer, or #NULL on failure.
@@ -486,10 +511,9 @@ dbus_server_listen (const char *address,
DBusServer *server;
DBusAddressEntry **entries;
int len, i;
- const char *address_problem_type;
- const char *address_problem_field;
- const char *address_problem_other;
-
+ DBusError first_connect_error;
+ dbus_bool_t handled_once;
+
_dbus_return_val_if_fail (address != NULL, NULL);
_dbus_return_val_if_error_is_set (error, NULL);
@@ -497,161 +521,111 @@ dbus_server_listen (const char *address,
return NULL;
server = NULL;
- address_problem_type = NULL;
- address_problem_field = NULL;
- address_problem_other = NULL;
+ dbus_error_init (&first_connect_error);
+ handled_once = FALSE;
for (i = 0; i < len; i++)
{
- const char *method;
+ int j;
- method = dbus_address_entry_get_method (entries[i]);
+ for (j = 0; j < (int) _DBUS_N_ELEMENTS (listen_funcs); ++j)
+ {
+ DBusServerListenResult result;
+ DBusError tmp_error;
+
+ dbus_error_init (&tmp_error);
+ result = (* listen_funcs[j].func) (entries[i],
+ &server,
+ &tmp_error);
- 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");
- const char *abstract = dbus_address_entry_get_value (entries[i], "abstract");
-
- if (path == NULL && tmpdir == NULL && abstract == NULL)
+ if (result == DBUS_SERVER_LISTEN_OK)
{
- address_problem_type = "unix";
- address_problem_field = "path or tmpdir or abstract";
- goto bad_address;
+ _dbus_assert (server != NULL);
+ _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
+ handled_once = TRUE;
+ goto out;
}
-
- if ((path && tmpdir) ||
- (path && abstract) ||
- (tmpdir && abstract))
+ else if (result == DBUS_SERVER_LISTEN_BAD_ADDRESS)
{
- address_problem_other = "cannot specify two of \"path\" and \"tmpdir\" and \"abstract\" at the same time";
- goto bad_address;
+ _dbus_assert (server == NULL);
+ _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
+ dbus_move_error (&tmp_error, error);
+ handled_once = TRUE;
+ goto out;
}
-
- if (tmpdir != NULL)
+ else if (result == DBUS_SERVER_LISTEN_NOT_HANDLED)
{
- 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;
- }
-
- /* Always use abstract namespace if possible with tmpdir */
-
- server =
- _dbus_server_new_for_domain_socket (_dbus_string_get_const_data (&full_path),
-#ifdef HAVE_ABSTRACT_SOCKETS
- TRUE,
-#else
- FALSE,
-#endif
- error);
+ _dbus_assert (server == NULL);
+ _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
- _dbus_string_free (&full_path);
- _dbus_string_free (&filename);
+ /* keep trying addresses */
}
- else
+ else if (result == DBUS_SERVER_LISTEN_DID_NOT_CONNECT)
{
- if (path)
- server = _dbus_server_new_for_domain_socket (path, FALSE, error);
+ _dbus_assert (server == NULL);
+ _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
+ if (!dbus_error_is_set (&first_connect_error))
+ dbus_move_error (&tmp_error, &first_connect_error);
else
- server = _dbus_server_new_for_domain_socket (abstract, TRUE, error);
- }
- }
- else if (strcmp (method, "tcp") == 0)
- {
- const char *host = dbus_address_entry_get_value (entries[i], "host");
- const char *port = dbus_address_entry_get_value (entries[i], "port");
- DBusString str;
- long lport;
- dbus_bool_t sresult;
-
- if (port == NULL)
- {
- address_problem_type = "tcp";
- address_problem_field = "port";
- goto bad_address;
- }
+ dbus_error_free (&tmp_error);
- _dbus_string_init_const (&str, port);
- sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
- _dbus_string_free (&str);
-
- if (sresult == FALSE || lport <= 0 || lport > 65535)
- {
- address_problem_other = "Port is not an integer between 0 and 65535";
- goto bad_address;
+ handled_once = TRUE;
+
+ /* keep trying addresses */
}
-
- server = _dbus_server_new_for_tcp_socket (host, lport, error);
+ }
- if (server)
- break;
- }
-#ifdef DBUS_BUILD_TESTS
- else if (strcmp (method, "debug-pipe") == 0)
- {
- const char *name = dbus_address_entry_get_value (entries[i], "name");
+ _dbus_assert (server == NULL);
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ }
- if (name == NULL)
- {
- address_problem_type = "debug-pipe";
- address_problem_field = "name";
- goto bad_address;
- }
+ out:
- server = _dbus_server_debug_pipe_new (name, error);
- }
-#endif
+ if (!handled_once)
+ {
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ if (len > 0)
+ dbus_set_error (error,
+ DBUS_ERROR_BAD_ADDRESS,
+ "Unknown address type '%s'",
+ dbus_address_entry_get_method (entries[0]));
else
- {
- address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")";
- goto bad_address;
- }
-
- if (server)
- break;
+ dbus_set_error (error,
+ DBUS_ERROR_BAD_ADDRESS,
+ "Empty address '%s'",
+ address);
}
-
- out:
dbus_address_entries_free (entries);
- return server;
- bad_address:
- dbus_address_entries_free (entries);
- if (address_problem_type != NULL)
- dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
- "Server address of type %s was missing argument %s",
- address_problem_type, address_problem_field);
- else
- dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
- "Could not parse server address: %s",
- address_problem_other);
+ if (server == NULL)
+ {
+ _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error) ||
+ dbus_error_is_set (error));
+
+ if (error && dbus_error_is_set (error))
+ {
+ /* already set the error */
+ }
+ else
+ {
+ /* didn't set the error but either error should be
+ * NULL or first_connect_error should be set.
+ */
+ _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error));
+ dbus_move_error (&first_connect_error, error);
+ }
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (&first_connect_error); /* be sure we freed it */
+ _DBUS_ASSERT_ERROR_IS_SET (error);
- return NULL;
+ return NULL;
+ }
+ else
+ {
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ return server;
+ }
}
/**
@@ -1166,17 +1140,30 @@ _dbus_server_test (void)
for (i = 0; i < _DBUS_N_ELEMENTS (valid_addresses); i++)
{
- server = dbus_server_listen (valid_addresses[i], NULL);
+ DBusError error;
+
+ /* FIXME um, how are the two tests here different? */
+
+ dbus_error_init (&error);
+ server = dbus_server_listen (valid_addresses[i], &error);
if (server == NULL)
- _dbus_assert_not_reached ("Failed to listen for valid address.");
+ {
+ _dbus_warn ("server listen error: %s: %s\n", error.name, error.message);
+ dbus_error_free (&error);
+ _dbus_assert_not_reached ("Failed to listen for valid address.");
+ }
dbus_server_disconnect (server);
dbus_server_unref (server);
/* Try disconnecting before unreffing */
- server = dbus_server_listen (valid_addresses[i], NULL);
+ server = dbus_server_listen (valid_addresses[i], &error);
if (server == NULL)
- _dbus_assert_not_reached ("Failed to listen for valid address.");
+ {
+ _dbus_warn ("server listen error: %s: %s\n", error.name, error.message);
+ dbus_error_free (&error);
+ _dbus_assert_not_reached ("Failed to listen for valid address.");
+ }
dbus_server_disconnect (server);
dbus_server_unref (server);