mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-14 14:28:16 +02:00
2003-03-16 Havoc Pennington <hp@pobox.com>
* dbus/dbus-watch.c (_dbus_watch_new): handle failure to malloc the watch * dbus/dbus-server-debug-pipe.c (_dbus_transport_debug_pipe_new): add some missing dbus_set_result * bus/dispatch.c (bus_dispatch_add_connection): handle failure to alloc the DBusMessageHandler * dbus/dbus-transport.c (_dbus_transport_disconnect): don't ref the transport here, since we call this from the finalizer; it resulted in a double-finalize. * dbus/dbus-transport.c (_dbus_transport_disconnect): fix a bug where we tried to use transport->connection that was NULL, happened when transport was disconnected early on due to OOM * bus/*.c: adapt to handle OOM for watches/timeouts * dbus/dbus-transport-unix.c: port to handle OOM during watch handling * dbus/dbus-auth.c (_dbus_auth_get_unused_bytes): return a reference to unused bytes instead of a copy * dbus/dbus-server.c (dbus_server_handle_watch): return FALSE for out of memory * dbus/dbus-connection.c (dbus_connection_handle_watch): return FALSE on OOM * dbus/dbus-timeout.c (dbus_timeout_handle): return FALSE for out of memory
This commit is contained in:
parent
3caaa342e8
commit
b4a1100f4f
29 changed files with 581 additions and 371 deletions
36
ChangeLog
36
ChangeLog
|
|
@ -1,3 +1,39 @@
|
||||||
|
2003-03-16 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
|
* dbus/dbus-watch.c (_dbus_watch_new): handle failure to malloc
|
||||||
|
the watch
|
||||||
|
|
||||||
|
* dbus/dbus-server-debug-pipe.c (_dbus_transport_debug_pipe_new):
|
||||||
|
add some missing dbus_set_result
|
||||||
|
|
||||||
|
* bus/dispatch.c (bus_dispatch_add_connection): handle failure to
|
||||||
|
alloc the DBusMessageHandler
|
||||||
|
|
||||||
|
* dbus/dbus-transport.c (_dbus_transport_disconnect): don't ref
|
||||||
|
the transport here, since we call this from the finalizer; it
|
||||||
|
resulted in a double-finalize.
|
||||||
|
|
||||||
|
* dbus/dbus-transport.c (_dbus_transport_disconnect): fix a bug
|
||||||
|
where we tried to use transport->connection that was NULL,
|
||||||
|
happened when transport was disconnected early on due to OOM
|
||||||
|
|
||||||
|
* bus/*.c: adapt to handle OOM for watches/timeouts
|
||||||
|
|
||||||
|
* dbus/dbus-transport-unix.c: port to handle OOM during
|
||||||
|
watch handling
|
||||||
|
|
||||||
|
* dbus/dbus-auth.c (_dbus_auth_get_unused_bytes): return a
|
||||||
|
reference to unused bytes instead of a copy
|
||||||
|
|
||||||
|
* dbus/dbus-server.c (dbus_server_handle_watch): return FALSE for
|
||||||
|
out of memory
|
||||||
|
|
||||||
|
* dbus/dbus-connection.c (dbus_connection_handle_watch): return
|
||||||
|
FALSE on OOM
|
||||||
|
|
||||||
|
* dbus/dbus-timeout.c (dbus_timeout_handle): return FALSE for out
|
||||||
|
of memory
|
||||||
|
|
||||||
2003-03-16 Anders Carlsson <andersca@codefactory.se>
|
2003-03-16 Anders Carlsson <andersca@codefactory.se>
|
||||||
|
|
||||||
* doc/dbus-specification.sgml:
|
* doc/dbus-specification.sgml:
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,14 @@ struct BusContext
|
||||||
BusRegistry *registry;
|
BusRegistry *registry;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
server_watch_callback (DBusWatch *watch,
|
server_watch_callback (DBusWatch *watch,
|
||||||
unsigned int condition,
|
unsigned int condition,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
BusContext *context = data;
|
BusContext *context = data;
|
||||||
|
|
||||||
dbus_server_handle_watch (context->server, watch, condition);
|
return dbus_server_handle_watch (context->server, watch, condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
static dbus_bool_t
|
static dbus_bool_t
|
||||||
|
|
@ -69,6 +69,7 @@ static void
|
||||||
server_timeout_callback (DBusTimeout *timeout,
|
server_timeout_callback (DBusTimeout *timeout,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
|
/* can return FALSE on OOM but we just let it fire again later */
|
||||||
dbus_timeout_handle (timeout);
|
dbus_timeout_handle (timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -133,20 +133,23 @@ bus_connection_disconnected (DBusConnection *connection)
|
||||||
dbus_connection_unref (connection);
|
dbus_connection_unref (connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
connection_watch_callback (DBusWatch *watch,
|
connection_watch_callback (DBusWatch *watch,
|
||||||
unsigned int condition,
|
unsigned int condition,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
DBusConnection *connection = data;
|
DBusConnection *connection = data;
|
||||||
|
dbus_bool_t retval;
|
||||||
|
|
||||||
dbus_connection_ref (connection);
|
dbus_connection_ref (connection);
|
||||||
|
|
||||||
dbus_connection_handle_watch (connection, watch, condition);
|
retval = dbus_connection_handle_watch (connection, watch, condition);
|
||||||
|
|
||||||
bus_connection_dispatch_all_messages (connection);
|
bus_connection_dispatch_all_messages (connection);
|
||||||
|
|
||||||
dbus_connection_unref (connection);
|
dbus_connection_unref (connection);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dbus_bool_t
|
static dbus_bool_t
|
||||||
|
|
@ -171,7 +174,8 @@ connection_timeout_callback (DBusTimeout *timeout,
|
||||||
DBusConnection *connection = data;
|
DBusConnection *connection = data;
|
||||||
|
|
||||||
dbus_connection_ref (connection);
|
dbus_connection_ref (connection);
|
||||||
|
|
||||||
|
/* can return FALSE on OOM but we just let it fire again later */
|
||||||
dbus_timeout_handle (timeout);
|
dbus_timeout_handle (timeout);
|
||||||
|
|
||||||
bus_connection_dispatch_all_messages (connection);
|
bus_connection_dispatch_all_messages (connection);
|
||||||
|
|
|
||||||
|
|
@ -365,7 +365,12 @@ bus_dispatch_add_connection (DBusConnection *connection)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
handler = dbus_message_handler_new (bus_dispatch_message_handler, NULL, NULL);
|
handler = dbus_message_handler_new (bus_dispatch_message_handler, NULL, NULL);
|
||||||
|
if (handler == NULL)
|
||||||
|
{
|
||||||
|
message_handler_slot_unref ();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dbus_connection_add_filter (connection, handler))
|
if (!dbus_connection_add_filter (connection, handler))
|
||||||
{
|
{
|
||||||
dbus_message_handler_unref (handler);
|
dbus_message_handler_unref (handler);
|
||||||
|
|
|
||||||
35
bus/loop.c
35
bus/loop.c
|
|
@ -50,6 +50,8 @@ typedef struct
|
||||||
Callback callback;
|
Callback callback;
|
||||||
BusWatchFunction function;
|
BusWatchFunction function;
|
||||||
DBusWatch *watch;
|
DBusWatch *watch;
|
||||||
|
/* last watch handle failed due to OOM */
|
||||||
|
unsigned int last_iteration_oom : 1;
|
||||||
} WatchCallback;
|
} WatchCallback;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
@ -78,6 +80,7 @@ watch_callback_new (DBusWatch *watch,
|
||||||
|
|
||||||
cb->watch = watch;
|
cb->watch = watch;
|
||||||
cb->function = function;
|
cb->function = function;
|
||||||
|
cb->last_iteration_oom = FALSE;
|
||||||
cb->callback.type = CALLBACK_WATCH;
|
cb->callback.type = CALLBACK_WATCH;
|
||||||
cb->callback.data = data;
|
cb->callback.data = data;
|
||||||
cb->callback.free_data_func = free_data_func;
|
cb->callback.free_data_func = free_data_func;
|
||||||
|
|
@ -278,11 +281,13 @@ bus_loop_iterate (dbus_bool_t block)
|
||||||
int n_ready;
|
int n_ready;
|
||||||
int initial_serial;
|
int initial_serial;
|
||||||
long timeout;
|
long timeout;
|
||||||
|
dbus_bool_t oom_watch_pending;
|
||||||
|
|
||||||
retval = FALSE;
|
retval = FALSE;
|
||||||
|
|
||||||
fds = NULL;
|
fds = NULL;
|
||||||
watches_for_fds = NULL;
|
watches_for_fds = NULL;
|
||||||
|
oom_watch_pending = FALSE;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
_dbus_verbose (" iterate %d timeouts %d watches\n",
|
_dbus_verbose (" iterate %d timeouts %d watches\n",
|
||||||
|
|
@ -306,7 +311,8 @@ bus_loop_iterate (dbus_bool_t block)
|
||||||
{
|
{
|
||||||
WatchCallback *wcb = WATCH_CALLBACK (cb);
|
WatchCallback *wcb = WATCH_CALLBACK (cb);
|
||||||
|
|
||||||
if (dbus_watch_get_enabled (wcb->watch))
|
if (!wcb->last_iteration_oom &&
|
||||||
|
dbus_watch_get_enabled (wcb->watch))
|
||||||
++n_fds;
|
++n_fds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -341,7 +347,15 @@ bus_loop_iterate (dbus_bool_t block)
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
WatchCallback *wcb = WATCH_CALLBACK (cb);
|
WatchCallback *wcb = WATCH_CALLBACK (cb);
|
||||||
|
|
||||||
if (dbus_watch_get_enabled (wcb->watch))
|
if (wcb->last_iteration_oom)
|
||||||
|
{
|
||||||
|
/* we skip this one this time, but reenable it next time,
|
||||||
|
* and have a timeout on this iteration
|
||||||
|
*/
|
||||||
|
wcb->last_iteration_oom = FALSE;
|
||||||
|
oom_watch_pending = TRUE;
|
||||||
|
}
|
||||||
|
else if (dbus_watch_get_enabled (wcb->watch))
|
||||||
{
|
{
|
||||||
watches_for_fds[i] = wcb;
|
watches_for_fds[i] = wcb;
|
||||||
|
|
||||||
|
|
@ -423,7 +437,13 @@ bus_loop_iterate (dbus_bool_t block)
|
||||||
|
|
||||||
if (!block)
|
if (!block)
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
|
|
||||||
|
/* if a watch is OOM, don't wait longer than the OOM
|
||||||
|
* wait to re-enable it
|
||||||
|
*/
|
||||||
|
if (oom_watch_pending)
|
||||||
|
timeout = MIN (timeout, bus_get_oom_wait ());
|
||||||
|
|
||||||
n_ready = _dbus_poll (fds, n_fds, timeout);
|
n_ready = _dbus_poll (fds, n_fds, timeout);
|
||||||
|
|
||||||
initial_serial = callback_list_serial;
|
initial_serial = callback_list_serial;
|
||||||
|
|
@ -538,9 +558,10 @@ bus_loop_iterate (dbus_bool_t block)
|
||||||
if (condition != 0 &&
|
if (condition != 0 &&
|
||||||
dbus_watch_get_enabled (wcb->watch))
|
dbus_watch_get_enabled (wcb->watch))
|
||||||
{
|
{
|
||||||
(* wcb->function) (wcb->watch,
|
if (!(* wcb->function) (wcb->watch,
|
||||||
condition,
|
condition,
|
||||||
((Callback*)wcb)->data);
|
((Callback*)wcb)->data))
|
||||||
|
wcb->last_iteration_oom = TRUE;
|
||||||
|
|
||||||
retval = TRUE;
|
retval = TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
bus/loop.h
10
bus/loop.h
|
|
@ -26,11 +26,11 @@
|
||||||
|
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
|
|
||||||
typedef void (* BusWatchFunction) (DBusWatch *watch,
|
typedef dbus_bool_t (* BusWatchFunction) (DBusWatch *watch,
|
||||||
unsigned int condition,
|
unsigned int condition,
|
||||||
void *data);
|
void *data);
|
||||||
typedef void (* BusTimeoutFunction) (DBusTimeout *timeout,
|
typedef void (* BusTimeoutFunction) (DBusTimeout *timeout,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
dbus_bool_t bus_loop_add_watch (DBusWatch *watch,
|
dbus_bool_t bus_loop_add_watch (DBusWatch *watch,
|
||||||
BusWatchFunction function,
|
BusWatchFunction function,
|
||||||
|
|
|
||||||
12
bus/test.c
12
bus/test.c
|
|
@ -35,18 +35,21 @@
|
||||||
*/
|
*/
|
||||||
static DBusList *clients = NULL;
|
static DBusList *clients = NULL;
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
client_watch_callback (DBusWatch *watch,
|
client_watch_callback (DBusWatch *watch,
|
||||||
unsigned int condition,
|
unsigned int condition,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
DBusConnection *connection = data;
|
DBusConnection *connection = data;
|
||||||
|
dbus_bool_t retval;
|
||||||
|
|
||||||
dbus_connection_ref (connection);
|
dbus_connection_ref (connection);
|
||||||
|
|
||||||
dbus_connection_handle_watch (connection, watch, condition);
|
retval = dbus_connection_handle_watch (connection, watch, condition);
|
||||||
|
|
||||||
dbus_connection_unref (connection);
|
dbus_connection_unref (connection);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dbus_bool_t
|
static dbus_bool_t
|
||||||
|
|
@ -71,7 +74,8 @@ client_timeout_callback (DBusTimeout *timeout,
|
||||||
DBusConnection *connection = data;
|
DBusConnection *connection = data;
|
||||||
|
|
||||||
dbus_connection_ref (connection);
|
dbus_connection_ref (connection);
|
||||||
|
|
||||||
|
/* can return FALSE on OOM but we just let it fire again later */
|
||||||
dbus_timeout_handle (timeout);
|
dbus_timeout_handle (timeout);
|
||||||
|
|
||||||
dbus_connection_unref (connection);
|
dbus_connection_unref (connection);
|
||||||
|
|
|
||||||
14
bus/utils.c
14
bus/utils.c
|
|
@ -28,17 +28,23 @@
|
||||||
|
|
||||||
const char bus_no_memory_message[] = "Memory allocation failure in message bus";
|
const char bus_no_memory_message[] = "Memory allocation failure in message bus";
|
||||||
|
|
||||||
void
|
int
|
||||||
bus_wait_for_memory (void)
|
bus_get_oom_wait (void)
|
||||||
{
|
{
|
||||||
#ifdef DBUS_BUILD_TESTS
|
#ifdef DBUS_BUILD_TESTS
|
||||||
/* make tests go fast */
|
/* make tests go fast */
|
||||||
_dbus_sleep_milliseconds (10);
|
return 10;
|
||||||
#else
|
#else
|
||||||
_dbus_sleep_milliseconds (500);
|
return 500;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bus_wait_for_memory (void)
|
||||||
|
{
|
||||||
|
_dbus_sleep_milliseconds (bus_get_oom_wait ());
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bus_connection_dispatch_all_messages (DBusConnection *connection)
|
bus_connection_dispatch_all_messages (DBusConnection *connection)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
|
|
||||||
|
int bus_get_oom_wait (void);
|
||||||
void bus_wait_for_memory (void);
|
void bus_wait_for_memory (void);
|
||||||
|
|
||||||
extern const char bus_no_memory_message[];
|
extern const char bus_no_memory_message[];
|
||||||
|
|
|
||||||
|
|
@ -437,14 +437,23 @@ _dbus_auth_script_run (const DBusString *filename)
|
||||||
_dbus_string_free (&username);
|
_dbus_string_free (&username);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_dbus_auth_bytes_received (auth, &to_send))
|
|
||||||
{
|
|
||||||
_dbus_warn ("not enough memory to call bytes_received, or can't add bytes to auth object already in end state\n");
|
|
||||||
_dbus_string_free (&to_send);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
{
|
||||||
|
DBusString *buffer;
|
||||||
|
|
||||||
|
_dbus_auth_get_buffer (auth, &buffer);
|
||||||
|
if (!_dbus_string_copy (&to_send, 0,
|
||||||
|
buffer, _dbus_string_get_length (buffer)))
|
||||||
|
{
|
||||||
|
_dbus_warn ("not enough memory to call bytes_received, or can't add bytes to auth object already in end state\n");
|
||||||
|
_dbus_string_free (&to_send);
|
||||||
|
_dbus_auth_return_buffer (auth, buffer, 0);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dbus_auth_return_buffer (auth, buffer, _dbus_string_get_length (&to_send));
|
||||||
|
}
|
||||||
|
|
||||||
_dbus_string_free (&to_send);
|
_dbus_string_free (&to_send);
|
||||||
}
|
}
|
||||||
else if (_dbus_string_starts_with_c_str (&line,
|
else if (_dbus_string_starts_with_c_str (&line,
|
||||||
|
|
@ -510,7 +519,7 @@ _dbus_auth_script_run (const DBusString *filename)
|
||||||
"EXPECT_UNUSED"))
|
"EXPECT_UNUSED"))
|
||||||
{
|
{
|
||||||
DBusString expected;
|
DBusString expected;
|
||||||
DBusString unused;
|
const DBusString *unused;
|
||||||
|
|
||||||
_dbus_string_delete_first_word (&line);
|
_dbus_string_delete_first_word (&line);
|
||||||
|
|
||||||
|
|
@ -528,35 +537,20 @@ _dbus_auth_script_run (const DBusString *filename)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_dbus_string_init (&unused, _DBUS_INT_MAX))
|
_dbus_auth_get_unused_bytes (auth, &unused);
|
||||||
{
|
|
||||||
_dbus_warn ("no mem to allocate string unused\n");
|
|
||||||
_dbus_string_free (&expected);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_dbus_auth_get_unused_bytes (auth, &unused))
|
|
||||||
{
|
|
||||||
_dbus_warn ("couldn't get unused bytes\n");
|
|
||||||
_dbus_string_free (&expected);
|
|
||||||
_dbus_string_free (&unused);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_dbus_string_equal (&expected, &unused))
|
if (_dbus_string_equal (&expected, unused))
|
||||||
{
|
{
|
||||||
_dbus_string_free (&expected);
|
_dbus_string_free (&expected);
|
||||||
_dbus_string_free (&unused);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char *e1, *h1;
|
const char *e1, *h1;
|
||||||
_dbus_string_get_const_data (&expected, &e1);
|
_dbus_string_get_const_data (&expected, &e1);
|
||||||
_dbus_string_get_const_data (&unused, &h1);
|
_dbus_string_get_const_data (unused, &h1);
|
||||||
_dbus_warn ("Expected unused bytes '%s' and have '%s'\n",
|
_dbus_warn ("Expected unused bytes '%s' and have '%s'\n",
|
||||||
e1, h1);
|
e1, h1);
|
||||||
_dbus_string_free (&expected);
|
_dbus_string_free (&expected);
|
||||||
_dbus_string_free (&unused);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,7 @@ struct DBusAuth
|
||||||
unsigned int authenticated_pending_begin : 1; /**< Authenticated once we get BEGIN */
|
unsigned int authenticated_pending_begin : 1; /**< Authenticated once we get BEGIN */
|
||||||
unsigned int already_got_mechanisms : 1; /**< Client already got mech list */
|
unsigned int already_got_mechanisms : 1; /**< Client already got mech list */
|
||||||
unsigned int already_asked_for_initial_response : 1; /**< Already sent a blank challenge to get an initial response */
|
unsigned int already_asked_for_initial_response : 1; /**< Already sent a blank challenge to get an initial response */
|
||||||
|
unsigned int buffer_outstanding : 1; /**< Buffer is "checked out" for reading data into */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
@ -1996,35 +1997,40 @@ _dbus_auth_bytes_sent (DBusAuth *auth,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores bytes received from the peer we're conversing with.
|
* Get a buffer to be used for reading bytes from the peer we're conversing
|
||||||
|
* with. Bytes should be appended to this buffer.
|
||||||
*
|
*
|
||||||
* @param auth the auth conversation
|
* @param auth the auth conversation
|
||||||
* @param str the received bytes.
|
* @param buffer return location for buffer to append bytes to
|
||||||
* @returns #FALSE if not enough memory to store the bytes or we were already authenticated.
|
|
||||||
*/
|
*/
|
||||||
dbus_bool_t
|
void
|
||||||
_dbus_auth_bytes_received (DBusAuth *auth,
|
_dbus_auth_get_buffer (DBusAuth *auth,
|
||||||
const DBusString *str)
|
DBusString **buffer)
|
||||||
{
|
{
|
||||||
_dbus_assert (auth != NULL);
|
_dbus_assert (auth != NULL);
|
||||||
_dbus_assert (str != NULL);
|
_dbus_assert (!auth->buffer_outstanding);
|
||||||
|
|
||||||
if (DBUS_AUTH_IN_END_STATE (auth))
|
*buffer = &auth->incoming;
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
auth->needed_memory = FALSE;
|
auth->buffer_outstanding = TRUE;
|
||||||
|
}
|
||||||
if (!_dbus_string_copy (str, 0,
|
|
||||||
&auth->incoming,
|
|
||||||
_dbus_string_get_length (&auth->incoming)))
|
|
||||||
{
|
|
||||||
auth->needed_memory = TRUE;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dbus_auth_do_work (auth);
|
/**
|
||||||
|
* Returns a buffer with new data read into it.
|
||||||
return TRUE;
|
*
|
||||||
|
* @param auth the auth conversation
|
||||||
|
* @param buffer the buffer being returned
|
||||||
|
* @param bytes_read number of new bytes added
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_dbus_auth_return_buffer (DBusAuth *auth,
|
||||||
|
DBusString *buffer,
|
||||||
|
int bytes_read)
|
||||||
|
{
|
||||||
|
_dbus_assert (buffer == &auth->incoming);
|
||||||
|
_dbus_assert (auth->buffer_outstanding);
|
||||||
|
|
||||||
|
auth->buffer_outstanding = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2034,22 +2040,32 @@ _dbus_auth_bytes_received (DBusAuth *auth,
|
||||||
* succeeded.
|
* succeeded.
|
||||||
*
|
*
|
||||||
* @param auth the auth conversation
|
* @param auth the auth conversation
|
||||||
* @param str string to append the unused bytes to
|
* @param str return location for pointer to string of unused bytes
|
||||||
* @returns #FALSE if not enough memory to return the bytes
|
|
||||||
*/
|
*/
|
||||||
dbus_bool_t
|
void
|
||||||
_dbus_auth_get_unused_bytes (DBusAuth *auth,
|
_dbus_auth_get_unused_bytes (DBusAuth *auth,
|
||||||
DBusString *str)
|
const DBusString **str)
|
||||||
{
|
{
|
||||||
if (!DBUS_AUTH_IN_END_STATE (auth))
|
if (!DBUS_AUTH_IN_END_STATE (auth))
|
||||||
return FALSE;
|
return;
|
||||||
|
|
||||||
if (!_dbus_string_move (&auth->incoming,
|
|
||||||
0, str,
|
|
||||||
_dbus_string_get_length (str)))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
*str = &auth->incoming;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets rid of unused bytes returned by _dbus_auth_get_unused_bytes()
|
||||||
|
* after we've gotten them and successfully moved them elsewhere.
|
||||||
|
*
|
||||||
|
* @param auth the auth conversation
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_dbus_auth_delete_unused_bytes (DBusAuth *auth)
|
||||||
|
{
|
||||||
|
if (!DBUS_AUTH_IN_END_STATE (auth))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_dbus_string_set_length (&auth->incoming, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -42,34 +42,38 @@ typedef enum
|
||||||
DBUS_AUTH_STATE_AUTHENTICATED
|
DBUS_AUTH_STATE_AUTHENTICATED
|
||||||
} DBusAuthState;
|
} DBusAuthState;
|
||||||
|
|
||||||
DBusAuth* _dbus_auth_server_new (void);
|
DBusAuth* _dbus_auth_server_new (void);
|
||||||
DBusAuth* _dbus_auth_client_new (void);
|
DBusAuth* _dbus_auth_client_new (void);
|
||||||
void _dbus_auth_ref (DBusAuth *auth);
|
void _dbus_auth_ref (DBusAuth *auth);
|
||||||
void _dbus_auth_unref (DBusAuth *auth);
|
void _dbus_auth_unref (DBusAuth *auth);
|
||||||
DBusAuthState _dbus_auth_do_work (DBusAuth *auth);
|
DBusAuthState _dbus_auth_do_work (DBusAuth *auth);
|
||||||
dbus_bool_t _dbus_auth_get_bytes_to_send (DBusAuth *auth,
|
dbus_bool_t _dbus_auth_get_bytes_to_send (DBusAuth *auth,
|
||||||
const DBusString **str);
|
const DBusString **str);
|
||||||
void _dbus_auth_bytes_sent (DBusAuth *auth,
|
void _dbus_auth_bytes_sent (DBusAuth *auth,
|
||||||
int bytes_sent);
|
int bytes_sent);
|
||||||
dbus_bool_t _dbus_auth_bytes_received (DBusAuth *auth,
|
void _dbus_auth_get_buffer (DBusAuth *auth,
|
||||||
const DBusString *str);
|
DBusString **buffer);
|
||||||
dbus_bool_t _dbus_auth_get_unused_bytes (DBusAuth *auth,
|
void _dbus_auth_return_buffer (DBusAuth *auth,
|
||||||
DBusString *str);
|
DBusString *buffer,
|
||||||
dbus_bool_t _dbus_auth_needs_encoding (DBusAuth *auth);
|
int bytes_read);
|
||||||
dbus_bool_t _dbus_auth_encode_data (DBusAuth *auth,
|
void _dbus_auth_get_unused_bytes (DBusAuth *auth,
|
||||||
const DBusString *plaintext,
|
const DBusString **str);
|
||||||
DBusString *encoded);
|
void _dbus_auth_delete_unused_bytes (DBusAuth *auth);
|
||||||
dbus_bool_t _dbus_auth_needs_decoding (DBusAuth *auth);
|
dbus_bool_t _dbus_auth_needs_encoding (DBusAuth *auth);
|
||||||
dbus_bool_t _dbus_auth_decode_data (DBusAuth *auth,
|
dbus_bool_t _dbus_auth_encode_data (DBusAuth *auth,
|
||||||
const DBusString *encoded,
|
const DBusString *plaintext,
|
||||||
DBusString *plaintext);
|
DBusString *encoded);
|
||||||
void _dbus_auth_set_credentials (DBusAuth *auth,
|
dbus_bool_t _dbus_auth_needs_decoding (DBusAuth *auth);
|
||||||
const DBusCredentials *credentials);
|
dbus_bool_t _dbus_auth_decode_data (DBusAuth *auth,
|
||||||
|
const DBusString *encoded,
|
||||||
|
DBusString *plaintext);
|
||||||
|
void _dbus_auth_set_credentials (DBusAuth *auth,
|
||||||
|
const DBusCredentials *credentials);
|
||||||
|
void _dbus_auth_get_identity (DBusAuth *auth,
|
||||||
|
DBusCredentials *credentials);
|
||||||
|
dbus_bool_t _dbus_auth_set_context (DBusAuth *auth,
|
||||||
|
const DBusString *context);
|
||||||
|
|
||||||
void _dbus_auth_get_identity (DBusAuth *auth,
|
|
||||||
DBusCredentials *credentials);
|
|
||||||
dbus_bool_t _dbus_auth_set_context (DBusAuth *auth,
|
|
||||||
const DBusString *context);
|
|
||||||
|
|
||||||
DBUS_END_DECLS;
|
DBUS_END_DECLS;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1166,7 +1166,7 @@ dbus_connection_send (DBusConnection *connection,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
reply_handler_timeout (void *data)
|
reply_handler_timeout (void *data)
|
||||||
{
|
{
|
||||||
DBusConnection *connection;
|
DBusConnection *connection;
|
||||||
|
|
@ -1187,6 +1187,8 @@ reply_handler_timeout (void *data)
|
||||||
reply_handler_data->timeout_added = FALSE;
|
reply_handler_data->timeout_added = FALSE;
|
||||||
|
|
||||||
dbus_mutex_unlock (connection->mutex);
|
dbus_mutex_unlock (connection->mutex);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -2171,21 +2173,33 @@ dbus_connection_set_wakeup_main_function (DBusConnection *connection,
|
||||||
* is ready for reading or writing, or has an exception such
|
* is ready for reading or writing, or has an exception such
|
||||||
* as a hangup.
|
* as a hangup.
|
||||||
*
|
*
|
||||||
|
* If this function returns #FALSE, then the file descriptor may still
|
||||||
|
* be ready for reading or writing, but more memory is needed in order
|
||||||
|
* to do the reading or writing. If you ignore the #FALSE return, your
|
||||||
|
* application may spin in a busy loop on the file descriptor until
|
||||||
|
* memory becomes available, but nothing more catastrophic should
|
||||||
|
* happen.
|
||||||
|
*
|
||||||
* @param connection the connection.
|
* @param connection the connection.
|
||||||
* @param watch the watch.
|
* @param watch the watch.
|
||||||
* @param condition the current condition of the file descriptors being watched.
|
* @param condition the current condition of the file descriptors being watched.
|
||||||
|
* @returns #FALSE if the IO condition may not have been fully handled due to lack of memory
|
||||||
*/
|
*/
|
||||||
void
|
dbus_bool_t
|
||||||
dbus_connection_handle_watch (DBusConnection *connection,
|
dbus_connection_handle_watch (DBusConnection *connection,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int condition)
|
unsigned int condition)
|
||||||
{
|
{
|
||||||
|
dbus_bool_t retval;
|
||||||
|
|
||||||
dbus_mutex_lock (connection->mutex);
|
dbus_mutex_lock (connection->mutex);
|
||||||
_dbus_connection_acquire_io_path (connection, -1);
|
_dbus_connection_acquire_io_path (connection, -1);
|
||||||
_dbus_transport_handle_watch (connection->transport,
|
retval = _dbus_transport_handle_watch (connection->transport,
|
||||||
watch, condition);
|
watch, condition);
|
||||||
_dbus_connection_release_io_path (connection);
|
_dbus_connection_release_io_path (connection);
|
||||||
dbus_mutex_unlock (connection->mutex);
|
dbus_mutex_unlock (connection->mutex);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ void dbus_connection_set_wakeup_main_function (DBusConnection
|
||||||
DBusWakeupMainFunction wakeup_main_function,
|
DBusWakeupMainFunction wakeup_main_function,
|
||||||
void *data,
|
void *data,
|
||||||
DBusFreeFunction free_data_function);
|
DBusFreeFunction free_data_function);
|
||||||
void dbus_connection_handle_watch (DBusConnection *connection,
|
dbus_bool_t dbus_connection_handle_watch (DBusConnection *connection,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int condition);
|
unsigned int condition);
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ void* dbus_timeout_get_data (DBusTimeout *timeout);
|
||||||
void dbus_timeout_set_data (DBusTimeout *timeout,
|
void dbus_timeout_set_data (DBusTimeout *timeout,
|
||||||
void *data,
|
void *data,
|
||||||
DBusFreeFunction free_data_function);
|
DBusFreeFunction free_data_function);
|
||||||
void dbus_timeout_handle (DBusTimeout *timeout);
|
dbus_bool_t dbus_timeout_handle (DBusTimeout *timeout);
|
||||||
dbus_bool_t dbus_timeout_get_enabled (DBusTimeout *timeout);
|
dbus_bool_t dbus_timeout_get_enabled (DBusTimeout *timeout);
|
||||||
|
|
||||||
/* Handlers */
|
/* Handlers */
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,13 @@ debug_finalize (DBusServer *server)
|
||||||
dbus_free (server);
|
dbus_free (server);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
debug_handle_watch (DBusServer *server,
|
debug_handle_watch (DBusServer *server,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -211,6 +212,7 @@ _dbus_transport_debug_pipe_new (const char *server_name,
|
||||||
{
|
{
|
||||||
_dbus_close (client_fd, NULL);
|
_dbus_close (client_fd, NULL);
|
||||||
_dbus_close (server_fd, NULL);
|
_dbus_close (server_fd, NULL);
|
||||||
|
dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,6 +224,7 @@ _dbus_transport_debug_pipe_new (const char *server_name,
|
||||||
{
|
{
|
||||||
_dbus_transport_unref (client_transport);
|
_dbus_transport_unref (client_transport);
|
||||||
_dbus_close (server_fd, NULL);
|
_dbus_close (server_fd, NULL);
|
||||||
|
dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,6 +237,7 @@ _dbus_transport_debug_pipe_new (const char *server_name,
|
||||||
if (connection == NULL)
|
if (connection == NULL)
|
||||||
{
|
{
|
||||||
_dbus_transport_unref (client_transport);
|
_dbus_transport_unref (client_transport);
|
||||||
|
dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,11 +71,12 @@ debug_finalize (DBusServer *server)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
debug_handle_watch (DBusServer *server,
|
debug_handle_watch (DBusServer *server,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -184,7 +185,7 @@ typedef struct
|
||||||
DBusTimeout *timeout;
|
DBusTimeout *timeout;
|
||||||
} ServerAndTransport;
|
} ServerAndTransport;
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
handle_new_client (void *data)
|
handle_new_client (void *data)
|
||||||
{
|
{
|
||||||
ServerAndTransport *st = data;
|
ServerAndTransport *st = data;
|
||||||
|
|
@ -196,13 +197,13 @@ handle_new_client (void *data)
|
||||||
|
|
||||||
transport = _dbus_transport_debug_server_new (st->transport);
|
transport = _dbus_transport_debug_server_new (st->transport);
|
||||||
if (transport == NULL)
|
if (transport == NULL)
|
||||||
return;
|
return FALSE;
|
||||||
|
|
||||||
connection = _dbus_connection_new_for_transport (transport);
|
connection = _dbus_connection_new_for_transport (transport);
|
||||||
_dbus_transport_unref (transport);
|
_dbus_transport_unref (transport);
|
||||||
|
|
||||||
if (connection == NULL)
|
if (connection == NULL)
|
||||||
return;
|
return FALSE;
|
||||||
|
|
||||||
/* See if someone wants to handle this new connection,
|
/* See if someone wants to handle this new connection,
|
||||||
* self-referencing for paranoia
|
* self-referencing for paranoia
|
||||||
|
|
@ -223,6 +224,8 @@ handle_new_client (void *data)
|
||||||
|
|
||||||
/* killing timeout frees both "st" and "timeout" */
|
/* killing timeout frees both "st" and "timeout" */
|
||||||
_dbus_timeout_unref (st->timeout);
|
_dbus_timeout_unref (st->timeout);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -36,17 +36,17 @@ typedef struct DBusServerVTable DBusServerVTable;
|
||||||
|
|
||||||
struct DBusServerVTable
|
struct DBusServerVTable
|
||||||
{
|
{
|
||||||
void (* finalize) (DBusServer *server);
|
void (* finalize) (DBusServer *server);
|
||||||
/**< The finalize method must free the server. */
|
/**< The finalize method must free the server. */
|
||||||
|
|
||||||
void (* handle_watch) (DBusServer *server,
|
dbus_bool_t (* handle_watch) (DBusServer *server,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
/**< The handle_watch method handles reading/writing
|
/**< The handle_watch method handles reading/writing
|
||||||
* data as indicated by the flags.
|
* data as indicated by the flags.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void (* disconnect) (DBusServer *server);
|
void (* disconnect) (DBusServer *server);
|
||||||
/**< Disconnect this server. */
|
/**< Disconnect this server. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,8 @@ unix_finalize (DBusServer *server)
|
||||||
* us to drop the last ref to the connection before
|
* us to drop the last ref to the connection before
|
||||||
* disconnecting it. That is invalid.
|
* disconnecting it. That is invalid.
|
||||||
*/
|
*/
|
||||||
static void
|
/* Return value is just for memory, not other failures. */
|
||||||
|
static dbus_bool_t
|
||||||
handle_new_client_fd (DBusServer *server,
|
handle_new_client_fd (DBusServer *server,
|
||||||
int client_fd)
|
int client_fd)
|
||||||
{
|
{
|
||||||
|
|
@ -80,13 +81,13 @@ handle_new_client_fd (DBusServer *server,
|
||||||
_dbus_verbose ("Creating new client connection with fd %d\n", client_fd);
|
_dbus_verbose ("Creating new client connection with fd %d\n", client_fd);
|
||||||
|
|
||||||
if (!_dbus_set_fd_nonblocking (client_fd, NULL))
|
if (!_dbus_set_fd_nonblocking (client_fd, NULL))
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
transport = _dbus_transport_new_for_fd (client_fd, TRUE);
|
transport = _dbus_transport_new_for_fd (client_fd, TRUE);
|
||||||
if (transport == NULL)
|
if (transport == NULL)
|
||||||
{
|
{
|
||||||
close (client_fd);
|
close (client_fd);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* note that client_fd is now owned by the transport, and will be
|
/* note that client_fd is now owned by the transport, and will be
|
||||||
|
|
@ -97,7 +98,7 @@ handle_new_client_fd (DBusServer *server,
|
||||||
_dbus_transport_unref (transport);
|
_dbus_transport_unref (transport);
|
||||||
|
|
||||||
if (connection == NULL)
|
if (connection == NULL)
|
||||||
return;
|
return FALSE;
|
||||||
|
|
||||||
_dbus_connection_set_connection_counter (connection,
|
_dbus_connection_set_connection_counter (connection,
|
||||||
server->connection_counter);
|
server->connection_counter);
|
||||||
|
|
@ -116,9 +117,11 @@ handle_new_client_fd (DBusServer *server,
|
||||||
|
|
||||||
/* If no one grabbed a reference, the connection will die. */
|
/* If no one grabbed a reference, the connection will die. */
|
||||||
dbus_connection_unref (connection);
|
dbus_connection_unref (connection);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
unix_handle_watch (DBusServer *server,
|
unix_handle_watch (DBusServer *server,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
|
|
@ -151,7 +154,9 @@ unix_handle_watch (DBusServer *server,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_dbus_fd_set_close_on_exec (client_fd);
|
_dbus_fd_set_close_on_exec (client_fd);
|
||||||
handle_new_client_fd (server, client_fd);
|
|
||||||
|
if (!handle_new_client_fd (server, client_fd))
|
||||||
|
_dbus_verbose ("Rejected client connection due to lack of memory\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,6 +165,8 @@ unix_handle_watch (DBusServer *server,
|
||||||
|
|
||||||
if (flags & DBUS_WATCH_HANGUP)
|
if (flags & DBUS_WATCH_HANGUP)
|
||||||
_dbus_verbose ("Hangup on server listening socket\n");
|
_dbus_verbose ("Hangup on server listening socket\n");
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
|
|
@ -498,12 +498,19 @@ dbus_server_set_timeout_functions (DBusServer *server,
|
||||||
* Called to notify the server when a previously-added watch
|
* Called to notify the server when a previously-added watch
|
||||||
* is ready for reading or writing, or has an exception such
|
* is ready for reading or writing, or has an exception such
|
||||||
* as a hangup.
|
* as a hangup.
|
||||||
|
*
|
||||||
|
* If this function returns #FALSE, then the file descriptor may still
|
||||||
|
* be ready for reading or writing, but more memory is needed in order
|
||||||
|
* to do the reading or writing. If you ignore the #FALSE return, your
|
||||||
|
* application may spin in a busy loop on the file descriptor until
|
||||||
|
* memory becomes available, but nothing more catastrophic should
|
||||||
|
* happen.
|
||||||
*
|
*
|
||||||
* @param server the server.
|
* @param server the server.
|
||||||
* @param watch the watch.
|
* @param watch the watch.
|
||||||
* @param condition the current condition of the file descriptors being watched.
|
* @param condition the current condition of the file descriptors being watched.
|
||||||
*/
|
*/
|
||||||
void
|
dbus_bool_t
|
||||||
dbus_server_handle_watch (DBusServer *server,
|
dbus_server_handle_watch (DBusServer *server,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int condition)
|
unsigned int condition)
|
||||||
|
|
@ -512,7 +519,7 @@ dbus_server_handle_watch (DBusServer *server,
|
||||||
|
|
||||||
_dbus_watch_sanitize_condition (watch, &condition);
|
_dbus_watch_sanitize_condition (watch, &condition);
|
||||||
|
|
||||||
(* server->vtable->handle_watch) (server, watch, condition);
|
return (* server->vtable->handle_watch) (server, watch, condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ dbus_bool_t dbus_server_set_timeout_functions (DBusServer *
|
||||||
DBusTimeoutToggledFunction toggled_function,
|
DBusTimeoutToggledFunction toggled_function,
|
||||||
void *data,
|
void *data,
|
||||||
DBusFreeFunction free_data_function);
|
DBusFreeFunction free_data_function);
|
||||||
void dbus_server_handle_watch (DBusServer *server,
|
dbus_bool_t dbus_server_handle_watch (DBusServer *server,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int condition);
|
unsigned int condition);
|
||||||
void dbus_server_set_max_connections (DBusServer *server,
|
void dbus_server_set_max_connections (DBusServer *server,
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,8 @@ _dbus_getenv (const char *varname)
|
||||||
* the data it reads to the DBusString buffer. It appends
|
* the data it reads to the DBusString buffer. It appends
|
||||||
* up to the given count, and returns the same value
|
* up to the given count, and returns the same value
|
||||||
* and same errno as read(). The only exception is that
|
* and same errno as read(). The only exception is that
|
||||||
* _dbus_read() handles EINTR for you.
|
* _dbus_read() handles EINTR for you. _dbus_read() can
|
||||||
|
* return ENOMEM, even though regular UNIX read doesn't.
|
||||||
*
|
*
|
||||||
* @param fd the file descriptor to read from
|
* @param fd the file descriptor to read from
|
||||||
* @param buffer the buffer to append data to
|
* @param buffer the buffer to append data to
|
||||||
|
|
|
||||||
|
|
@ -405,12 +405,19 @@ dbus_timeout_set_data (DBusTimeout *timeout,
|
||||||
* This function should be called when the timeout
|
* This function should be called when the timeout
|
||||||
* occurs.
|
* occurs.
|
||||||
*
|
*
|
||||||
|
* If this function returns #FALSE, then there wasn't
|
||||||
|
* enough memory to handle the timeout. Typically just
|
||||||
|
* letting the timeout fire again next time it naturally
|
||||||
|
* times out is an adequate response to that problem,
|
||||||
|
* but you could try to do more if you wanted.
|
||||||
|
*
|
||||||
* @param timeout the DBusTimeout object.
|
* @param timeout the DBusTimeout object.
|
||||||
|
* @returns #FALSE if there wasn't enough memory
|
||||||
*/
|
*/
|
||||||
void
|
dbus_bool_t
|
||||||
dbus_timeout_handle (DBusTimeout *timeout)
|
dbus_timeout_handle (DBusTimeout *timeout)
|
||||||
{
|
{
|
||||||
(* timeout->handler) (timeout->handler_data);
|
return (* timeout->handler) (timeout->handler_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ typedef struct DBusTimeoutList DBusTimeoutList;
|
||||||
|
|
||||||
/* Public methods on DBusTimeout are in dbus-connection.h */
|
/* Public methods on DBusTimeout are in dbus-connection.h */
|
||||||
|
|
||||||
typedef void (* DBusTimeoutHandler) (void *data);
|
typedef dbus_bool_t (* DBusTimeoutHandler) (void *data);
|
||||||
|
|
||||||
DBusTimeout* _dbus_timeout_new (int interval,
|
DBusTimeout* _dbus_timeout_new (int interval,
|
||||||
DBusTimeoutHandler handler,
|
DBusTimeoutHandler handler,
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,13 @@
|
||||||
#define DEFAULT_INTERVAL 1
|
#define DEFAULT_INTERVAL 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hack due to lack of OOM handling in a couple places
|
* Hack due to lack of OOM handling in a couple places.
|
||||||
|
* Need to alloc timeout permanently and enabled/disable so
|
||||||
|
* that check_timeout won't fail in messages_pending
|
||||||
*/
|
*/
|
||||||
#define WAIT_FOR_MEMORY() _dbus_sleep_milliseconds (250)
|
#define WAIT_FOR_MEMORY() _dbus_sleep_milliseconds (250)
|
||||||
|
|
||||||
static void check_timeout (DBusTransport *transport);
|
static dbus_bool_t check_timeout (DBusTransport *transport);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opaque object representing a debug transport.
|
* Opaque object representing a debug transport.
|
||||||
|
|
@ -123,18 +125,21 @@ move_messages (DBusTransport *transport)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
timeout_handler (void *data)
|
timeout_handler (void *data)
|
||||||
{
|
{
|
||||||
DBusTransport *transport = data;
|
DBusTransport *transport = data;
|
||||||
|
|
||||||
while (!move_messages (transport))
|
if (!move_messages (transport))
|
||||||
WAIT_FOR_MEMORY ();
|
return FALSE;
|
||||||
|
|
||||||
check_timeout (transport);
|
if (!check_timeout (transport))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
check_timeout (DBusTransport *transport)
|
check_timeout (DBusTransport *transport)
|
||||||
{
|
{
|
||||||
DBusTransportDebug *debug_transport = (DBusTransportDebug*) transport;
|
DBusTransportDebug *debug_transport = (DBusTransportDebug*) transport;
|
||||||
|
|
@ -150,9 +155,9 @@ check_timeout (DBusTransport *transport)
|
||||||
/* FIXME this can be fixed now, by enabling/disabling
|
/* FIXME this can be fixed now, by enabling/disabling
|
||||||
* the timeout instead of adding it here
|
* the timeout instead of adding it here
|
||||||
*/
|
*/
|
||||||
while (!_dbus_connection_add_timeout (transport->connection,
|
if (!_dbus_connection_add_timeout (transport->connection,
|
||||||
debug_transport->timeout))
|
debug_transport->timeout))
|
||||||
WAIT_FOR_MEMORY ();
|
return FALSE;
|
||||||
debug_transport->timeout_added = TRUE;
|
debug_transport->timeout_added = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -165,6 +170,8 @@ check_timeout (DBusTransport *transport)
|
||||||
debug_transport->timeout_added = FALSE;
|
debug_transport->timeout_added = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -189,11 +196,12 @@ debug_finalize (DBusTransport *transport)
|
||||||
dbus_free (transport);
|
dbus_free (transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
debug_handle_watch (DBusTransport *transport,
|
debug_handle_watch (DBusTransport *transport,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -204,7 +212,8 @@ debug_disconnect (DBusTransport *transport)
|
||||||
static dbus_bool_t
|
static dbus_bool_t
|
||||||
debug_connection_set (DBusTransport *transport)
|
debug_connection_set (DBusTransport *transport)
|
||||||
{
|
{
|
||||||
check_timeout (transport);
|
if (!check_timeout (transport))
|
||||||
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -212,7 +221,8 @@ static void
|
||||||
debug_messages_pending (DBusTransport *transport,
|
debug_messages_pending (DBusTransport *transport,
|
||||||
int messages_pending)
|
int messages_pending)
|
||||||
{
|
{
|
||||||
check_timeout (transport);
|
while (!check_timeout (transport))
|
||||||
|
WAIT_FOR_MEMORY ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
|
|
@ -36,36 +36,36 @@ typedef struct DBusTransportVTable DBusTransportVTable;
|
||||||
|
|
||||||
struct DBusTransportVTable
|
struct DBusTransportVTable
|
||||||
{
|
{
|
||||||
void (* finalize) (DBusTransport *transport);
|
void (* finalize) (DBusTransport *transport);
|
||||||
/**< The finalize method must free the transport. */
|
/**< The finalize method must free the transport. */
|
||||||
|
|
||||||
void (* handle_watch) (DBusTransport *transport,
|
dbus_bool_t (* handle_watch) (DBusTransport *transport,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
/**< The handle_watch method handles reading/writing
|
/**< The handle_watch method handles reading/writing
|
||||||
* data as indicated by the flags.
|
* data as indicated by the flags.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void (* disconnect) (DBusTransport *transport);
|
void (* disconnect) (DBusTransport *transport);
|
||||||
/**< Disconnect this transport. */
|
/**< Disconnect this transport. */
|
||||||
|
|
||||||
dbus_bool_t (* connection_set) (DBusTransport *transport);
|
dbus_bool_t (* connection_set) (DBusTransport *transport);
|
||||||
/**< Called when transport->connection has been filled in */
|
/**< Called when transport->connection has been filled in */
|
||||||
|
|
||||||
void (* messages_pending) (DBusTransport *transport,
|
void (* messages_pending) (DBusTransport *transport,
|
||||||
int queue_length);
|
int queue_length);
|
||||||
/**< Called when the outgoing message queue goes from empty
|
/**< Called when the outgoing message queue goes from empty
|
||||||
* to non-empty or vice versa.
|
* to non-empty or vice versa.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void (* do_iteration) (DBusTransport *transport,
|
void (* do_iteration) (DBusTransport *transport,
|
||||||
unsigned int flags,
|
unsigned int flags,
|
||||||
int timeout_milliseconds);
|
int timeout_milliseconds);
|
||||||
/**< Called to do a single "iteration" (block on select/poll
|
/**< Called to do a single "iteration" (block on select/poll
|
||||||
* followed by reading or writing data).
|
* followed by reading or writing data).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void (* live_messages_changed) (DBusTransport *transport);
|
void (* live_messages_changed) (DBusTransport *transport);
|
||||||
/**< Outstanding messages counter changed */
|
/**< Outstanding messages counter changed */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,12 @@ struct DBusTransportUnix
|
||||||
* outgoing message that have
|
* outgoing message that have
|
||||||
* been written.
|
* been written.
|
||||||
*/
|
*/
|
||||||
DBusString encoded_message; /**< Encoded version of current
|
DBusString encoded_outgoing; /**< Encoded version of current
|
||||||
* outgoing message.
|
* outgoing message.
|
||||||
*/
|
*/
|
||||||
|
DBusString encoded_incoming; /**< Encoded version of current
|
||||||
|
* incoming data.
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -99,7 +102,8 @@ unix_finalize (DBusTransport *transport)
|
||||||
|
|
||||||
free_watches (transport);
|
free_watches (transport);
|
||||||
|
|
||||||
_dbus_string_free (&unix_transport->encoded_message);
|
_dbus_string_free (&unix_transport->encoded_outgoing);
|
||||||
|
_dbus_string_free (&unix_transport->encoded_incoming);
|
||||||
|
|
||||||
_dbus_transport_finalize_base (transport);
|
_dbus_transport_finalize_base (transport);
|
||||||
|
|
||||||
|
|
@ -180,51 +184,39 @@ do_io_error (DBusTransport *transport)
|
||||||
|
|
||||||
/* return value is whether we successfully read any new data. */
|
/* return value is whether we successfully read any new data. */
|
||||||
static dbus_bool_t
|
static dbus_bool_t
|
||||||
read_data_into_auth (DBusTransport *transport)
|
read_data_into_auth (DBusTransport *transport,
|
||||||
|
dbus_bool_t *oom)
|
||||||
{
|
{
|
||||||
DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
|
DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
|
||||||
DBusString buffer;
|
DBusString *buffer;
|
||||||
int bytes_read;
|
int bytes_read;
|
||||||
|
|
||||||
if (!_dbus_string_init (&buffer, _DBUS_INT_MAX))
|
*oom = FALSE;
|
||||||
{
|
|
||||||
/* just disconnect if we don't have memory
|
_dbus_auth_get_buffer (transport->auth, &buffer);
|
||||||
* to do an authentication
|
|
||||||
*/
|
|
||||||
_dbus_verbose ("No memory for authentication\n");
|
|
||||||
do_io_error (transport);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes_read = _dbus_read (unix_transport->fd,
|
bytes_read = _dbus_read (unix_transport->fd,
|
||||||
&buffer, unix_transport->max_bytes_read_per_iteration);
|
buffer, unix_transport->max_bytes_read_per_iteration);
|
||||||
|
|
||||||
|
_dbus_auth_return_buffer (transport->auth, buffer,
|
||||||
|
bytes_read > 0 ? bytes_read : 0);
|
||||||
|
|
||||||
if (bytes_read > 0)
|
if (bytes_read > 0)
|
||||||
{
|
{
|
||||||
_dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
|
_dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
|
||||||
|
|
||||||
if (_dbus_auth_bytes_received (transport->auth,
|
return TRUE;
|
||||||
&buffer))
|
|
||||||
{
|
|
||||||
_dbus_string_free (&buffer);
|
|
||||||
return TRUE; /* We did read some data! woo! */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* just disconnect if we don't have memory to do an
|
|
||||||
* authentication, don't fool with trying to save the buffer
|
|
||||||
* and who knows what.
|
|
||||||
*/
|
|
||||||
_dbus_verbose ("No memory for authentication\n");
|
|
||||||
do_io_error (transport);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (bytes_read < 0)
|
else if (bytes_read < 0)
|
||||||
{
|
{
|
||||||
/* EINTR already handled for us */
|
/* EINTR already handled for us */
|
||||||
|
|
||||||
if (errno == EAGAIN ||
|
if (errno == ENOMEM)
|
||||||
errno == EWOULDBLOCK)
|
{
|
||||||
|
*oom = TRUE;
|
||||||
|
}
|
||||||
|
else if (errno == EAGAIN ||
|
||||||
|
errno == EWOULDBLOCK)
|
||||||
; /* do nothing, just return FALSE below */
|
; /* do nothing, just return FALSE below */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -232,15 +224,18 @@ read_data_into_auth (DBusTransport *transport)
|
||||||
_dbus_strerror (errno));
|
_dbus_strerror (errno));
|
||||||
do_io_error (transport);
|
do_io_error (transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
else if (bytes_read == 0)
|
else
|
||||||
{
|
{
|
||||||
|
_dbus_assert (bytes_read == 0);
|
||||||
|
|
||||||
_dbus_verbose ("Disconnected from remote app\n");
|
_dbus_verbose ("Disconnected from remote app\n");
|
||||||
do_io_error (transport);
|
do_io_error (transport);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_dbus_string_free (&buffer);
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return value is whether we successfully wrote any bytes */
|
/* Return value is whether we successfully wrote any bytes */
|
||||||
|
|
@ -282,98 +277,6 @@ write_data_from_auth (DBusTransport *transport)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
recover_unused_bytes (DBusTransport *transport)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (_dbus_auth_needs_decoding (transport->auth))
|
|
||||||
{
|
|
||||||
DBusString plaintext;
|
|
||||||
DBusString encoded;
|
|
||||||
DBusString *buffer;
|
|
||||||
int orig_len;
|
|
||||||
|
|
||||||
if (!_dbus_string_init (&plaintext, _DBUS_INT_MAX))
|
|
||||||
goto nomem;
|
|
||||||
|
|
||||||
if (!_dbus_string_init (&encoded, _DBUS_INT_MAX))
|
|
||||||
{
|
|
||||||
_dbus_string_free (&plaintext);
|
|
||||||
goto nomem;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_dbus_auth_get_unused_bytes (transport->auth,
|
|
||||||
&encoded))
|
|
||||||
{
|
|
||||||
_dbus_string_free (&plaintext);
|
|
||||||
_dbus_string_free (&encoded);
|
|
||||||
goto nomem;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_dbus_auth_decode_data (transport->auth,
|
|
||||||
&encoded, &plaintext))
|
|
||||||
{
|
|
||||||
_dbus_string_free (&plaintext);
|
|
||||||
_dbus_string_free (&encoded);
|
|
||||||
goto nomem;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dbus_message_loader_get_buffer (transport->loader,
|
|
||||||
&buffer);
|
|
||||||
|
|
||||||
orig_len = _dbus_string_get_length (buffer);
|
|
||||||
|
|
||||||
if (!_dbus_string_move (&plaintext, 0, buffer,
|
|
||||||
orig_len))
|
|
||||||
{
|
|
||||||
_dbus_string_free (&plaintext);
|
|
||||||
_dbus_string_free (&encoded);
|
|
||||||
goto nomem;
|
|
||||||
}
|
|
||||||
|
|
||||||
_dbus_verbose (" %d unused bytes sent to message loader\n",
|
|
||||||
_dbus_string_get_length (buffer) -
|
|
||||||
orig_len);
|
|
||||||
|
|
||||||
_dbus_message_loader_return_buffer (transport->loader,
|
|
||||||
buffer,
|
|
||||||
_dbus_string_get_length (buffer) -
|
|
||||||
orig_len);
|
|
||||||
|
|
||||||
_dbus_string_free (&plaintext);
|
|
||||||
_dbus_string_free (&encoded);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBusString *buffer;
|
|
||||||
int orig_len;
|
|
||||||
|
|
||||||
_dbus_message_loader_get_buffer (transport->loader,
|
|
||||||
&buffer);
|
|
||||||
|
|
||||||
orig_len = _dbus_string_get_length (buffer);
|
|
||||||
|
|
||||||
if (!_dbus_auth_get_unused_bytes (transport->auth,
|
|
||||||
buffer))
|
|
||||||
goto nomem;
|
|
||||||
|
|
||||||
_dbus_verbose (" %d unused bytes sent to message loader\n",
|
|
||||||
_dbus_string_get_length (buffer) -
|
|
||||||
orig_len);
|
|
||||||
|
|
||||||
_dbus_message_loader_return_buffer (transport->loader,
|
|
||||||
buffer,
|
|
||||||
_dbus_string_get_length (buffer) -
|
|
||||||
orig_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
nomem:
|
|
||||||
_dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
|
|
||||||
do_io_error (transport);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
exchange_credentials (DBusTransport *transport,
|
exchange_credentials (DBusTransport *transport,
|
||||||
dbus_bool_t do_reading,
|
dbus_bool_t do_reading,
|
||||||
|
|
@ -418,16 +321,20 @@ exchange_credentials (DBusTransport *transport,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
do_authentication (DBusTransport *transport,
|
do_authentication (DBusTransport *transport,
|
||||||
dbus_bool_t do_reading,
|
dbus_bool_t do_reading,
|
||||||
dbus_bool_t do_writing)
|
dbus_bool_t do_writing)
|
||||||
{
|
{
|
||||||
|
dbus_bool_t oom;
|
||||||
|
|
||||||
_dbus_transport_ref (transport);
|
_dbus_transport_ref (transport);
|
||||||
|
|
||||||
|
oom = FALSE;
|
||||||
|
|
||||||
while (!_dbus_transport_get_is_authenticated (transport) &&
|
while (!_dbus_transport_get_is_authenticated (transport) &&
|
||||||
_dbus_transport_get_is_connected (transport))
|
_dbus_transport_get_is_connected (transport))
|
||||||
{
|
{
|
||||||
exchange_credentials (transport, do_reading, do_writing);
|
exchange_credentials (transport, do_reading, do_writing);
|
||||||
|
|
||||||
if (transport->send_credentials_pending ||
|
if (transport->send_credentials_pending ||
|
||||||
|
|
@ -443,14 +350,14 @@ do_authentication (DBusTransport *transport,
|
||||||
{
|
{
|
||||||
case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
|
case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
|
||||||
_dbus_verbose (" auth state: waiting for input\n");
|
_dbus_verbose (" auth state: waiting for input\n");
|
||||||
if (!do_reading || !read_data_into_auth (transport))
|
if (!do_reading || !read_data_into_auth (transport, &oom))
|
||||||
goto out;
|
goto out;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
|
case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
|
||||||
/* Screw it, just disconnect */
|
|
||||||
_dbus_verbose (" auth state: waiting for memory\n");
|
_dbus_verbose (" auth state: waiting for memory\n");
|
||||||
do_io_error (transport);
|
oom = TRUE;
|
||||||
|
goto out;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
|
case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
|
||||||
|
|
@ -466,7 +373,8 @@ do_authentication (DBusTransport *transport,
|
||||||
|
|
||||||
case DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES:
|
case DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES:
|
||||||
_dbus_verbose (" auth state: auth with unused bytes\n");
|
_dbus_verbose (" auth state: auth with unused bytes\n");
|
||||||
recover_unused_bytes (transport);
|
/* We'll recover the unused bytes in dbus-transport.c */
|
||||||
|
goto out;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DBUS_AUTH_STATE_AUTHENTICATED:
|
case DBUS_AUTH_STATE_AUTHENTICATED:
|
||||||
|
|
@ -474,26 +382,34 @@ do_authentication (DBusTransport *transport,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
check_read_watch (transport);
|
check_read_watch (transport);
|
||||||
check_write_watch (transport);
|
check_write_watch (transport);
|
||||||
_dbus_transport_unref (transport);
|
_dbus_transport_unref (transport);
|
||||||
|
|
||||||
|
if (oom)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* returns false on oom */
|
||||||
|
static dbus_bool_t
|
||||||
do_writing (DBusTransport *transport)
|
do_writing (DBusTransport *transport)
|
||||||
{
|
{
|
||||||
int total;
|
int total;
|
||||||
DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
|
DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
|
||||||
|
dbus_bool_t oom;
|
||||||
|
|
||||||
/* No messages without authentication! */
|
/* No messages without authentication! */
|
||||||
if (!_dbus_transport_get_is_authenticated (transport))
|
if (!_dbus_transport_get_is_authenticated (transport))
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
if (transport->disconnected)
|
if (transport->disconnected)
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
|
oom = FALSE;
|
||||||
total = 0;
|
total = 0;
|
||||||
|
|
||||||
while (!transport->disconnected &&
|
while (!transport->disconnected &&
|
||||||
|
|
@ -513,9 +429,9 @@ do_writing (DBusTransport *transport)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unix_transport->write_watch == NULL)
|
if (!dbus_watch_get_enabled (unix_transport->write_watch))
|
||||||
{
|
{
|
||||||
_dbus_verbose ("write watch removed, not writing more stuff\n");
|
_dbus_verbose ("write watch disabled, not writing more stuff\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -535,21 +451,25 @@ do_writing (DBusTransport *transport)
|
||||||
|
|
||||||
if (_dbus_auth_needs_encoding (transport->auth))
|
if (_dbus_auth_needs_encoding (transport->auth))
|
||||||
{
|
{
|
||||||
if (_dbus_string_get_length (&unix_transport->encoded_message) == 0)
|
if (_dbus_string_get_length (&unix_transport->encoded_outgoing) == 0)
|
||||||
{
|
{
|
||||||
if (!_dbus_auth_encode_data (transport->auth,
|
if (!_dbus_auth_encode_data (transport->auth,
|
||||||
header, &unix_transport->encoded_message))
|
header, &unix_transport->encoded_outgoing))
|
||||||
goto out;
|
{
|
||||||
|
oom = TRUE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_dbus_auth_encode_data (transport->auth,
|
if (!_dbus_auth_encode_data (transport->auth,
|
||||||
body, &unix_transport->encoded_message))
|
body, &unix_transport->encoded_outgoing))
|
||||||
{
|
{
|
||||||
_dbus_string_set_length (&unix_transport->encoded_message, 0);
|
_dbus_string_set_length (&unix_transport->encoded_outgoing, 0);
|
||||||
|
oom = TRUE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
total_bytes_to_write = _dbus_string_get_length (&unix_transport->encoded_message);
|
total_bytes_to_write = _dbus_string_get_length (&unix_transport->encoded_outgoing);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
_dbus_verbose ("encoded message is %d bytes\n",
|
_dbus_verbose ("encoded message is %d bytes\n",
|
||||||
|
|
@ -558,7 +478,7 @@ do_writing (DBusTransport *transport)
|
||||||
|
|
||||||
bytes_written =
|
bytes_written =
|
||||||
_dbus_write (unix_transport->fd,
|
_dbus_write (unix_transport->fd,
|
||||||
&unix_transport->encoded_message,
|
&unix_transport->encoded_outgoing,
|
||||||
unix_transport->message_bytes_written,
|
unix_transport->message_bytes_written,
|
||||||
total_bytes_to_write - unix_transport->message_bytes_written);
|
total_bytes_to_write - unix_transport->message_bytes_written);
|
||||||
}
|
}
|
||||||
|
|
@ -621,7 +541,7 @@ do_writing (DBusTransport *transport)
|
||||||
if (unix_transport->message_bytes_written == total_bytes_to_write)
|
if (unix_transport->message_bytes_written == total_bytes_to_write)
|
||||||
{
|
{
|
||||||
unix_transport->message_bytes_written = 0;
|
unix_transport->message_bytes_written = 0;
|
||||||
_dbus_string_set_length (&unix_transport->encoded_message, 0);
|
_dbus_string_set_length (&unix_transport->encoded_outgoing, 0);
|
||||||
|
|
||||||
_dbus_connection_message_sent (transport->connection,
|
_dbus_connection_message_sent (transport->connection,
|
||||||
message);
|
message);
|
||||||
|
|
@ -630,20 +550,27 @@ do_writing (DBusTransport *transport)
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return; /* I think some C compilers require a statement after a label */
|
if (oom)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* returns false on out-of-memory */
|
||||||
|
static dbus_bool_t
|
||||||
do_reading (DBusTransport *transport)
|
do_reading (DBusTransport *transport)
|
||||||
{
|
{
|
||||||
DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
|
DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
|
||||||
DBusString *buffer;
|
DBusString *buffer;
|
||||||
int bytes_read;
|
int bytes_read;
|
||||||
int total;
|
int total;
|
||||||
|
dbus_bool_t oom;
|
||||||
|
|
||||||
/* No messages without authentication! */
|
/* No messages without authentication! */
|
||||||
if (!_dbus_transport_get_is_authenticated (transport))
|
if (!_dbus_transport_get_is_authenticated (transport))
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
|
oom = FALSE;
|
||||||
|
|
||||||
total = 0;
|
total = 0;
|
||||||
|
|
||||||
|
|
@ -651,8 +578,8 @@ do_reading (DBusTransport *transport)
|
||||||
|
|
||||||
/* See if we've exceeded max messages and need to disable reading */
|
/* See if we've exceeded max messages and need to disable reading */
|
||||||
check_read_watch (transport);
|
check_read_watch (transport);
|
||||||
if (unix_transport->read_watch == NULL)
|
if (!dbus_watch_get_enabled (unix_transport->read_watch))
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
if (total > unix_transport->max_bytes_read_per_iteration)
|
if (total > unix_transport->max_bytes_read_per_iteration)
|
||||||
{
|
{
|
||||||
|
|
@ -666,15 +593,16 @@ do_reading (DBusTransport *transport)
|
||||||
|
|
||||||
if (_dbus_auth_needs_decoding (transport->auth))
|
if (_dbus_auth_needs_decoding (transport->auth))
|
||||||
{
|
{
|
||||||
DBusString encoded;
|
if (_dbus_string_get_length (&unix_transport->encoded_incoming) > 0)
|
||||||
|
bytes_read = _dbus_string_get_length (&unix_transport->encoded_incoming);
|
||||||
if (!_dbus_string_init (&encoded, _DBUS_INT_MAX))
|
else
|
||||||
goto out; /* not enough memory for the moment */
|
bytes_read = _dbus_read (unix_transport->fd,
|
||||||
|
&unix_transport->encoded_incoming,
|
||||||
bytes_read = _dbus_read (unix_transport->fd,
|
unix_transport->max_bytes_read_per_iteration);
|
||||||
&encoded,
|
|
||||||
unix_transport->max_bytes_read_per_iteration);
|
|
||||||
|
|
||||||
|
_dbus_assert (_dbus_string_get_length (&unix_transport->encoded_incoming) ==
|
||||||
|
bytes_read);
|
||||||
|
|
||||||
if (bytes_read > 0)
|
if (bytes_read > 0)
|
||||||
{
|
{
|
||||||
int orig_len;
|
int orig_len;
|
||||||
|
|
@ -685,24 +613,20 @@ do_reading (DBusTransport *transport)
|
||||||
orig_len = _dbus_string_get_length (buffer);
|
orig_len = _dbus_string_get_length (buffer);
|
||||||
|
|
||||||
if (!_dbus_auth_decode_data (transport->auth,
|
if (!_dbus_auth_decode_data (transport->auth,
|
||||||
&encoded, buffer))
|
&unix_transport->encoded_incoming,
|
||||||
|
buffer))
|
||||||
{
|
{
|
||||||
/* FIXME argh, we are really fucked here - nowhere to
|
_dbus_verbose ("Out of memory decoding incoming data\n");
|
||||||
* put "encoded" while we wait for more memory. Just
|
oom = TRUE;
|
||||||
* screw it for now and disconnect. The failure may be
|
goto out;
|
||||||
* due to badly-encoded data instead of lack of memory
|
|
||||||
* anyhow.
|
|
||||||
*/
|
|
||||||
_dbus_verbose ("Disconnected from remote app due to failure decoding data\n");
|
|
||||||
do_io_error (transport);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_dbus_message_loader_return_buffer (transport->loader,
|
_dbus_message_loader_return_buffer (transport->loader,
|
||||||
buffer,
|
buffer,
|
||||||
_dbus_string_get_length (buffer) - orig_len);
|
_dbus_string_get_length (buffer) - orig_len);
|
||||||
}
|
|
||||||
|
|
||||||
_dbus_string_free (&encoded);
|
_dbus_string_set_length (&unix_transport->encoded_incoming, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -720,9 +644,15 @@ do_reading (DBusTransport *transport)
|
||||||
if (bytes_read < 0)
|
if (bytes_read < 0)
|
||||||
{
|
{
|
||||||
/* EINTR already handled for us */
|
/* EINTR already handled for us */
|
||||||
|
|
||||||
if (errno == EAGAIN ||
|
if (errno == ENOMEM)
|
||||||
errno == EWOULDBLOCK)
|
{
|
||||||
|
_dbus_verbose ("Out of memory in read()/do_reading()\n");
|
||||||
|
oom = TRUE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
else if (errno == EAGAIN ||
|
||||||
|
errno == EWOULDBLOCK)
|
||||||
goto out;
|
goto out;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -745,7 +675,10 @@ do_reading (DBusTransport *transport)
|
||||||
total += bytes_read;
|
total += bytes_read;
|
||||||
|
|
||||||
if (_dbus_transport_queue_messages (transport) == DBUS_DISPATCH_NEED_MEMORY)
|
if (_dbus_transport_queue_messages (transport) == DBUS_DISPATCH_NEED_MEMORY)
|
||||||
goto out;
|
{
|
||||||
|
oom = TRUE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Try reading more data until we get EAGAIN and return, or
|
/* Try reading more data until we get EAGAIN and return, or
|
||||||
* exceed max bytes per iteration. If in blocking mode of
|
* exceed max bytes per iteration. If in blocking mode of
|
||||||
|
|
@ -755,10 +688,13 @@ do_reading (DBusTransport *transport)
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return; /* I think some C compilers require a statement after a label */
|
if (oom)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static dbus_bool_t
|
||||||
unix_handle_watch (DBusTransport *transport,
|
unix_handle_watch (DBusTransport *transport,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
|
|
@ -771,7 +707,7 @@ unix_handle_watch (DBusTransport *transport,
|
||||||
if (flags & (DBUS_WATCH_HANGUP | DBUS_WATCH_ERROR))
|
if (flags & (DBUS_WATCH_HANGUP | DBUS_WATCH_ERROR))
|
||||||
{
|
{
|
||||||
_dbus_transport_disconnect (transport);
|
_dbus_transport_disconnect (transport);
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watch == unix_transport->read_watch &&
|
if (watch == unix_transport->read_watch &&
|
||||||
|
|
@ -780,8 +716,11 @@ unix_handle_watch (DBusTransport *transport,
|
||||||
#if 0
|
#if 0
|
||||||
_dbus_verbose ("handling read watch\n");
|
_dbus_verbose ("handling read watch\n");
|
||||||
#endif
|
#endif
|
||||||
do_authentication (transport, TRUE, FALSE);
|
if (!do_authentication (transport, TRUE, FALSE))
|
||||||
do_reading (transport);
|
return FALSE;
|
||||||
|
|
||||||
|
if (!do_reading (transport))
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
else if (watch == unix_transport->write_watch &&
|
else if (watch == unix_transport->write_watch &&
|
||||||
(flags & DBUS_WATCH_WRITABLE))
|
(flags & DBUS_WATCH_WRITABLE))
|
||||||
|
|
@ -789,9 +728,14 @@ unix_handle_watch (DBusTransport *transport,
|
||||||
#if 0
|
#if 0
|
||||||
_dbus_verbose ("handling write watch\n");
|
_dbus_verbose ("handling write watch\n");
|
||||||
#endif
|
#endif
|
||||||
do_authentication (transport, FALSE, TRUE);
|
if (!do_authentication (transport, FALSE, TRUE))
|
||||||
do_writing (transport);
|
return FALSE;
|
||||||
|
|
||||||
|
if (!do_writing (transport))
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -1031,26 +975,30 @@ _dbus_transport_new_for_fd (int fd,
|
||||||
if (unix_transport == NULL)
|
if (unix_transport == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!_dbus_string_init (&unix_transport->encoded_message,
|
if (!_dbus_string_init (&unix_transport->encoded_outgoing,
|
||||||
_DBUS_INT_MAX))
|
_DBUS_INT_MAX))
|
||||||
goto failed_0;
|
goto failed_0;
|
||||||
|
|
||||||
|
if (!_dbus_string_init (&unix_transport->encoded_incoming,
|
||||||
|
_DBUS_INT_MAX))
|
||||||
|
goto failed_1;
|
||||||
|
|
||||||
unix_transport->write_watch = _dbus_watch_new (fd,
|
unix_transport->write_watch = _dbus_watch_new (fd,
|
||||||
DBUS_WATCH_WRITABLE,
|
DBUS_WATCH_WRITABLE,
|
||||||
FALSE);
|
FALSE);
|
||||||
if (unix_transport->write_watch == NULL)
|
if (unix_transport->write_watch == NULL)
|
||||||
goto failed_1;
|
goto failed_2;
|
||||||
|
|
||||||
unix_transport->read_watch = _dbus_watch_new (fd,
|
unix_transport->read_watch = _dbus_watch_new (fd,
|
||||||
DBUS_WATCH_READABLE,
|
DBUS_WATCH_READABLE,
|
||||||
FALSE);
|
FALSE);
|
||||||
if (unix_transport->read_watch == NULL)
|
if (unix_transport->read_watch == NULL)
|
||||||
goto failed_2;
|
goto failed_3;
|
||||||
|
|
||||||
if (!_dbus_transport_init_base (&unix_transport->base,
|
if (!_dbus_transport_init_base (&unix_transport->base,
|
||||||
&unix_vtable,
|
&unix_vtable,
|
||||||
server))
|
server))
|
||||||
goto failed_3;
|
goto failed_4;
|
||||||
|
|
||||||
unix_transport->fd = fd;
|
unix_transport->fd = fd;
|
||||||
unix_transport->message_bytes_written = 0;
|
unix_transport->message_bytes_written = 0;
|
||||||
|
|
@ -1061,12 +1009,14 @@ _dbus_transport_new_for_fd (int fd,
|
||||||
|
|
||||||
return (DBusTransport*) unix_transport;
|
return (DBusTransport*) unix_transport;
|
||||||
|
|
||||||
failed_3:
|
failed_4:
|
||||||
_dbus_watch_unref (unix_transport->read_watch);
|
_dbus_watch_unref (unix_transport->read_watch);
|
||||||
failed_2:
|
failed_3:
|
||||||
_dbus_watch_unref (unix_transport->write_watch);
|
_dbus_watch_unref (unix_transport->write_watch);
|
||||||
|
failed_2:
|
||||||
|
_dbus_string_free (&unix_transport->encoded_incoming);
|
||||||
failed_1:
|
failed_1:
|
||||||
_dbus_string_free (&unix_transport->encoded_message);
|
_dbus_string_free (&unix_transport->encoded_outgoing);
|
||||||
failed_0:
|
failed_0:
|
||||||
dbus_free (unix_transport);
|
dbus_free (unix_transport);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -265,6 +265,8 @@ _dbus_transport_open (const char *address,
|
||||||
void
|
void
|
||||||
_dbus_transport_ref (DBusTransport *transport)
|
_dbus_transport_ref (DBusTransport *transport)
|
||||||
{
|
{
|
||||||
|
_dbus_assert (transport->refcount > 0);
|
||||||
|
|
||||||
transport->refcount += 1;
|
transport->refcount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -306,14 +308,12 @@ _dbus_transport_disconnect (DBusTransport *transport)
|
||||||
if (transport->disconnected)
|
if (transport->disconnected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_dbus_transport_ref (transport);
|
|
||||||
(* transport->vtable->disconnect) (transport);
|
(* transport->vtable->disconnect) (transport);
|
||||||
|
|
||||||
transport->disconnected = TRUE;
|
transport->disconnected = TRUE;
|
||||||
|
|
||||||
_dbus_connection_notify_disconnected (transport->connection);
|
if (transport->connection)
|
||||||
|
_dbus_connection_notify_disconnected (transport->connection);
|
||||||
_dbus_transport_unref (transport);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -394,30 +394,35 @@ _dbus_transport_get_is_authenticated (DBusTransport *transport)
|
||||||
* @param transport the transport.
|
* @param transport the transport.
|
||||||
* @param watch the watch.
|
* @param watch the watch.
|
||||||
* @param condition the current state of the watched file descriptor.
|
* @param condition the current state of the watched file descriptor.
|
||||||
|
* @returns #FALSE if not enough memory to fully handle the watch
|
||||||
*/
|
*/
|
||||||
void
|
dbus_bool_t
|
||||||
_dbus_transport_handle_watch (DBusTransport *transport,
|
_dbus_transport_handle_watch (DBusTransport *transport,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int condition)
|
unsigned int condition)
|
||||||
{
|
{
|
||||||
|
dbus_bool_t retval;
|
||||||
|
|
||||||
_dbus_assert (transport->vtable->handle_watch != NULL);
|
_dbus_assert (transport->vtable->handle_watch != NULL);
|
||||||
|
|
||||||
if (transport->disconnected)
|
if (transport->disconnected)
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
if (dbus_watch_get_fd (watch) < 0)
|
if (dbus_watch_get_fd (watch) < 0)
|
||||||
{
|
{
|
||||||
_dbus_warn ("Tried to handle an invalidated watch; this watch should have been removed\n");
|
_dbus_warn ("Tried to handle an invalidated watch; this watch should have been removed\n");
|
||||||
return;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_dbus_watch_sanitize_condition (watch, &condition);
|
_dbus_watch_sanitize_condition (watch, &condition);
|
||||||
|
|
||||||
_dbus_transport_ref (transport);
|
_dbus_transport_ref (transport);
|
||||||
_dbus_watch_ref (watch);
|
_dbus_watch_ref (watch);
|
||||||
(* transport->vtable->handle_watch) (transport, watch, condition);
|
retval = (* transport->vtable->handle_watch) (transport, watch, condition);
|
||||||
_dbus_watch_unref (watch);
|
_dbus_watch_unref (watch);
|
||||||
_dbus_transport_unref (transport);
|
_dbus_transport_unref (transport);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -506,6 +511,98 @@ _dbus_transport_do_iteration (DBusTransport *transport,
|
||||||
_dbus_transport_unref (transport);
|
_dbus_transport_unref (transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static dbus_bool_t
|
||||||
|
recover_unused_bytes (DBusTransport *transport)
|
||||||
|
{
|
||||||
|
if (_dbus_auth_do_work (transport->auth) != DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (_dbus_auth_needs_decoding (transport->auth))
|
||||||
|
{
|
||||||
|
DBusString plaintext;
|
||||||
|
const DBusString *encoded;
|
||||||
|
DBusString *buffer;
|
||||||
|
int orig_len;
|
||||||
|
|
||||||
|
if (!_dbus_string_init (&plaintext, _DBUS_INT_MAX))
|
||||||
|
goto nomem;
|
||||||
|
|
||||||
|
_dbus_auth_get_unused_bytes (transport->auth,
|
||||||
|
&encoded);
|
||||||
|
|
||||||
|
if (!_dbus_auth_decode_data (transport->auth,
|
||||||
|
encoded, &plaintext))
|
||||||
|
{
|
||||||
|
_dbus_string_free (&plaintext);
|
||||||
|
goto nomem;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dbus_message_loader_get_buffer (transport->loader,
|
||||||
|
&buffer);
|
||||||
|
|
||||||
|
orig_len = _dbus_string_get_length (buffer);
|
||||||
|
|
||||||
|
if (!_dbus_string_move (&plaintext, 0, buffer,
|
||||||
|
orig_len))
|
||||||
|
{
|
||||||
|
_dbus_string_free (&plaintext);
|
||||||
|
goto nomem;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dbus_verbose (" %d unused bytes sent to message loader\n",
|
||||||
|
_dbus_string_get_length (buffer) -
|
||||||
|
orig_len);
|
||||||
|
|
||||||
|
_dbus_message_loader_return_buffer (transport->loader,
|
||||||
|
buffer,
|
||||||
|
_dbus_string_get_length (buffer) -
|
||||||
|
orig_len);
|
||||||
|
|
||||||
|
_dbus_auth_delete_unused_bytes (transport->auth);
|
||||||
|
|
||||||
|
_dbus_string_free (&plaintext);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const DBusString *bytes;
|
||||||
|
DBusString *buffer;
|
||||||
|
int orig_len;
|
||||||
|
dbus_bool_t succeeded;
|
||||||
|
|
||||||
|
_dbus_message_loader_get_buffer (transport->loader,
|
||||||
|
&buffer);
|
||||||
|
|
||||||
|
orig_len = _dbus_string_get_length (buffer);
|
||||||
|
|
||||||
|
_dbus_auth_get_unused_bytes (transport->auth,
|
||||||
|
&bytes);
|
||||||
|
|
||||||
|
succeeded = TRUE;
|
||||||
|
if (!_dbus_string_copy (bytes, 0, buffer, _dbus_string_get_length (buffer)))
|
||||||
|
succeeded = FALSE;
|
||||||
|
|
||||||
|
_dbus_verbose (" %d unused bytes sent to message loader\n",
|
||||||
|
_dbus_string_get_length (buffer) -
|
||||||
|
orig_len);
|
||||||
|
|
||||||
|
_dbus_message_loader_return_buffer (transport->loader,
|
||||||
|
buffer,
|
||||||
|
_dbus_string_get_length (buffer) -
|
||||||
|
orig_len);
|
||||||
|
|
||||||
|
if (succeeded)
|
||||||
|
_dbus_auth_delete_unused_bytes (transport->auth);
|
||||||
|
else
|
||||||
|
goto nomem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
nomem:
|
||||||
|
_dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports our current dispatch status (whether there's buffered
|
* Reports our current dispatch status (whether there's buffered
|
||||||
* data to be queued as messages, or not, or we need memory).
|
* data to be queued as messages, or not, or we need memory).
|
||||||
|
|
@ -519,6 +616,21 @@ _dbus_transport_get_dispatch_status (DBusTransport *transport)
|
||||||
if (_dbus_counter_get_value (transport->live_messages_size) >= transport->max_live_messages_size)
|
if (_dbus_counter_get_value (transport->live_messages_size) >= transport->max_live_messages_size)
|
||||||
return DBUS_DISPATCH_COMPLETE; /* complete for now */
|
return DBUS_DISPATCH_COMPLETE; /* complete for now */
|
||||||
|
|
||||||
|
if (!_dbus_transport_get_is_authenticated (transport))
|
||||||
|
{
|
||||||
|
switch (_dbus_auth_do_work (transport->auth))
|
||||||
|
{
|
||||||
|
case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
|
||||||
|
return DBUS_DISPATCH_NEED_MEMORY;
|
||||||
|
case DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES:
|
||||||
|
if (!recover_unused_bytes (transport))
|
||||||
|
return DBUS_DISPATCH_NEED_MEMORY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!_dbus_message_loader_queue_messages (transport->loader))
|
if (!_dbus_message_loader_queue_messages (transport->loader))
|
||||||
return DBUS_DISPATCH_NEED_MEMORY;
|
return DBUS_DISPATCH_NEED_MEMORY;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ void _dbus_transport_unref (DBusTransport *t
|
||||||
void _dbus_transport_disconnect (DBusTransport *transport);
|
void _dbus_transport_disconnect (DBusTransport *transport);
|
||||||
dbus_bool_t _dbus_transport_get_is_connected (DBusTransport *transport);
|
dbus_bool_t _dbus_transport_get_is_connected (DBusTransport *transport);
|
||||||
dbus_bool_t _dbus_transport_get_is_authenticated (DBusTransport *transport);
|
dbus_bool_t _dbus_transport_get_is_authenticated (DBusTransport *transport);
|
||||||
void _dbus_transport_handle_watch (DBusTransport *transport,
|
dbus_bool_t _dbus_transport_handle_watch (DBusTransport *transport,
|
||||||
DBusWatch *watch,
|
DBusWatch *watch,
|
||||||
unsigned int condition);
|
unsigned int condition);
|
||||||
dbus_bool_t _dbus_transport_set_connection (DBusTransport *transport,
|
dbus_bool_t _dbus_transport_set_connection (DBusTransport *transport,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,9 @@ _dbus_watch_new (int fd,
|
||||||
_dbus_assert ((flags & VALID_WATCH_FLAGS) == flags);
|
_dbus_assert ((flags & VALID_WATCH_FLAGS) == flags);
|
||||||
|
|
||||||
watch = dbus_new0 (DBusWatch, 1);
|
watch = dbus_new0 (DBusWatch, 1);
|
||||||
|
if (watch == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
watch->refcount = 1;
|
watch->refcount = 1;
|
||||||
watch->fd = fd;
|
watch->fd = fd;
|
||||||
watch->flags = flags;
|
watch->flags = flags;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue