/* dbus-connection.c DBusConnection object
*
* Copyright (C) 2002-2006 Red Hat Inc.
+ * Copyright (C) 2013 Samsung Electronics
*
* Licensed under the Academic Free License version 2.1
*
#include "dbus-threads-internal.h"
#include "dbus-bus.h"
#include "dbus-marshal-basic.h"
+#ifdef ENABLE_KDBUS_TRANSPORT
+#include "dbus-transport-kdbus.h"
+#include <stdlib.h>
+#endif
#ifdef DBUS_DISABLE_CHECKS
#define TOOK_LOCK_CHECK(connection)
* @{
*/
-#ifdef DBUS_ENABLE_VERBOSE_MODE
static void
_dbus_connection_trace_ref (DBusConnection *connection,
int old_refcount,
int new_refcount,
const char *why)
{
+#ifdef DBUS_ENABLE_VERBOSE_MODE
static int enabled = -1;
_dbus_trace_ref ("DBusConnection", connection, old_refcount, new_refcount,
why, "DBUS_CONNECTION_TRACE", &enabled);
-}
-#else
-#define _dbus_connection_trace_ref(c,o,n,w) \
- do \
- {\
- (void) (o); \
- (void) (n); \
- } while (0)
#endif
+}
/**
* Internal struct representing a message filter function
(*connection->wakeup_main_function) (connection->wakeup_main_data);
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/**
* Gets the locks so we can examine them
*
DBusPendingCall *pending;
dbus_uint32_t reply_serial;
DBusMessage *message;
-
- _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
-
+
+ _dbus_assert (_dbus_transport_peek_is_authenticated (connection->transport));
+
_dbus_list_append_link (&connection->incoming_messages,
link);
message = link->data;
*
* @param transport the transport.
* @returns the new connection, or #NULL on failure.
- */
+*/
+#ifdef ENABLE_KDBUS_TRANSPORT
+static DBusConnection*
+_dbus_connection_new_for_transport_internal (DBusTransport *transport, dbus_bool_t exists)
+#else
DBusConnection*
_dbus_connection_new_for_transport (DBusTransport *transport)
+#endif
{
DBusConnection *connection;
DBusWatchList *watch_list;
pending_replies =
_dbus_hash_table_new (DBUS_HASH_INT,
- NULL,
+ NULL,
(DBusFreeFunction)free_pending_call_on_hash_removal);
if (pending_replies == NULL)
goto error;
connection->route_peer_messages = FALSE;
connection->disconnected_message_arrived = FALSE;
connection->disconnected_message_processed = FALSE;
-
+
#if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
connection->generation = _dbus_current_generation;
#endif
connection->disconnect_message_link = disconnect_link;
- CONNECTION_LOCK (connection);
-
- if (!_dbus_transport_set_connection (transport, connection))
- {
- CONNECTION_UNLOCK (connection);
+#ifdef ENABLE_KDBUS_TRANSPORT
+ if(!exists)
+#endif
+ {
+ CONNECTION_LOCK (connection);
- goto error;
- }
+ if (!_dbus_transport_set_connection (transport, connection))
+ {
+ CONNECTION_UNLOCK (connection);
- _dbus_transport_ref (transport);
+ goto error;
+ }
- CONNECTION_UNLOCK (connection);
+ _dbus_transport_ref (transport);
+
+ CONNECTION_UNLOCK (connection);
+ }
_dbus_connection_trace_ref (connection, 0, 1, "new_for_transport");
return connection;
return NULL;
}
+#ifdef ENABLE_KDBUS_TRANSPORT
+/**
+ * Creates a new connection for the given transport. A transport
+ * represents a message stream that uses some concrete mechanism, such
+ * as UNIX domain sockets. May return #NULL if insufficient
+ * memory exists to create the connection.
+ *
+ * @param transport the transport.
+ * @returns the new connection, or #NULL on failure.
+ */
+DBusConnection*
+_dbus_connection_new_for_transport (DBusTransport *transport)
+{
+ return _dbus_connection_new_for_transport_internal(transport, FALSE);
+}
+
+DBusConnection*
+_dbus_connection_new_for_used_transport (DBusTransport *transport)
+{
+ return _dbus_connection_new_for_transport_internal(transport, TRUE);
+}
+#endif
+
/**
* Increments the reference count of a DBusConnection.
* Requires that the caller already holds the connection lock.
#ifndef DBUS_DISABLE_CHECKS
_dbus_assert (!connection->have_connection_lock);
#endif
+
return connection;
}
_dbus_sleep_milliseconds (1000);
}
-static DBusMessage *
+DBusMessage *
generate_local_error_message (dbus_uint32_t serial,
char *error_name,
char *error_msg)
dbus_message_unref (message);
}
-/* This is run without the mutex held, but after the last reference
- * to the connection has been dropped we should have no thread-related
- * problems
- */
+#ifdef ENABLE_KDBUS_TRANSPORT
+static void
+_dbus_connection_last_unref_internal (DBusConnection *connection, dbus_bool_t unref_transport)
+#else
static void
_dbus_connection_last_unref (DBusConnection *connection)
+#endif
{
DBusList *link;
/* You have to disconnect the connection before unref:ing it. Otherwise
* you won't get the disconnected message.
*/
- _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
+#ifdef ENABLE_KDBUS_TRANSPORT
+ if(unref_transport)
+#endif
+ _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
_dbus_assert (connection->server_guid == NULL);
/* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
+ dbus_connection_set_windows_user_function (connection, NULL, NULL, NULL);
_dbus_watch_list_free (connection->watches);
connection->watches = NULL;
_dbus_list_foreach (&connection->outgoing_messages,
free_outgoing_message,
- connection);
+ connection);
_dbus_list_clear (&connection->outgoing_messages);
_dbus_list_foreach (&connection->incoming_messages,
- (DBusForeachFunction) dbus_message_unref,
- NULL);
+ (DBusForeachFunction) dbus_message_unref,
+ NULL);
_dbus_list_clear (&connection->incoming_messages);
_dbus_counter_unref (connection->outgoing_counter);
- _dbus_transport_unref (connection->transport);
+#ifdef ENABLE_KDBUS_TRANSPORT
+ if(unref_transport)
+#endif
+ _dbus_transport_unref (connection->transport);
if (connection->disconnect_message_link)
{
dbus_free (connection);
}
+#ifdef ENABLE_KDBUS_TRANSPORT
+/* This is run without the mutex held, but after the last reference
+ * to the connection has been dropped we should have no thread-related
+ * problems
+ */
+static void
+_dbus_connection_last_unref (DBusConnection *connection)
+{
+ _dbus_connection_last_unref_internal(connection, TRUE);
+}
+#endif
+
/**
* Decrements the reference count of a DBusConnection, and finalizes
* it if the count reaches zero.
}
}
+#ifdef ENABLE_KDBUS_TRANSPORT
+void
+dbus_connection_unref_phantom (DBusConnection *connection)
+{
+ dbus_int32_t old_refcount;
+
+ _dbus_return_if_fail (connection != NULL);
+ _dbus_return_if_fail (connection->generation == _dbus_current_generation);
+
+ old_refcount = _dbus_atomic_dec (&connection->refcount);
+
+ _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1, "unref");
+
+ if (old_refcount == 1)
+ _dbus_connection_last_unref_internal(connection, FALSE);
+}
+#endif
+
/*
* Note that the transport can disconnect itself (other end drops us)
* and in that case this function never runs. So this function must
dbus_bool_t res;
_dbus_return_val_if_fail (connection != NULL, FALSE);
-
+
CONNECTION_LOCK (connection);
- res = _dbus_transport_get_is_authenticated (connection->transport);
+ res = _dbus_transport_try_to_authenticate (connection->transport);
CONNECTION_UNLOCK (connection);
return res;
}
+#ifdef ENABLE_KDBUS_TRANSPORT
+/**
+ * Sets authenticated status for connection. Needed for kdbus, where authentication is
+ * made in different manner.
+ * LOCK commented out because called with lock already set
+ * @param connection the connection
+ */
+dbus_bool_t
+dbus_connection_set_is_authenticated (DBusConnection *connection)
+{
+ _dbus_return_val_if_fail (connection != NULL, FALSE);
+
+// CONNECTION_LOCK (connection);
+ connection->transport->authenticated = TRUE;
+// CONNECTION_UNLOCK (connection);
+
+ return TRUE;
+}
+#endif
+
/**
* Gets whether the connection is not authenticated as a specific
* user. If the connection is not authenticated, this function
_dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
{
HAVE_LOCK_CHECK (connection);
-
+
if (connection->n_incoming > 0)
return DBUS_DISPATCH_DATA_REMAINS;
else if (!_dbus_transport_queue_messages (connection->transport))
{
DBusDispatchStatus status;
dbus_bool_t is_connected;
-
+
status = _dbus_transport_get_dispatch_status (connection->transport);
is_connected = _dbus_transport_get_is_connected (connection->transport);
return retval;
}
-
/**
* Gets the UNIX user ID of the connection if known. Returns #TRUE if
* the uid is filled in. Always returns #FALSE on non-UNIX platforms
* @param uid return location for the user ID
* @returns #TRUE if uid is filled in with a valid user ID
*/
+#ifdef ENABLE_KDBUS_TRANSPORT
+dbus_bool_t
+dbus_connection_get_unix_user_dbus (DBusConnection *connection,
+ unsigned long *uid)
+#else
dbus_bool_t
dbus_connection_get_unix_user (DBusConnection *connection,
unsigned long *uid)
+#endif
{
dbus_bool_t result;
_dbus_return_val_if_fail (connection != NULL, FALSE);
_dbus_return_val_if_fail (uid != NULL, FALSE);
-
+
CONNECTION_LOCK (connection);
- if (!_dbus_transport_get_is_authenticated (connection->transport))
+ if (!_dbus_transport_try_to_authenticate (connection->transport))
result = FALSE;
else
result = _dbus_transport_get_unix_user (connection->transport,
* @param pid return location for the process ID
* @returns #TRUE if uid is filled in with a valid process ID
*/
+#ifdef ENABLE_KDBUS_TRANSPORT
+dbus_bool_t
+dbus_connection_get_unix_process_id_dbus (DBusConnection *connection,
+ unsigned long *pid)
+#else
dbus_bool_t
dbus_connection_get_unix_process_id (DBusConnection *connection,
unsigned long *pid)
+#endif
{
dbus_bool_t result;
_dbus_return_val_if_fail (connection != NULL, FALSE);
_dbus_return_val_if_fail (pid != NULL, FALSE);
-
+
CONNECTION_LOCK (connection);
- if (!_dbus_transport_get_is_authenticated (connection->transport))
+ if (!_dbus_transport_try_to_authenticate (connection->transport))
result = FALSE;
else
result = _dbus_transport_get_unix_process_id (connection->transport,
* connection.
*
* @param connection the connection
- * @param data return location for audit data
+ * @param data return location for audit data
+ * @param data_size return location for length of audit data
* @returns #TRUE if audit data is filled in with a valid ucred pointer
*/
dbus_bool_t
_dbus_return_val_if_fail (connection != NULL, FALSE);
_dbus_return_val_if_fail (data != NULL, FALSE);
_dbus_return_val_if_fail (data_size != NULL, FALSE);
-
+
CONNECTION_LOCK (connection);
- if (!_dbus_transport_get_is_authenticated (connection->transport))
+ if (!_dbus_transport_try_to_authenticate (connection->transport))
result = FALSE;
else
result = _dbus_transport_get_adt_audit_session_data (connection->transport,
_dbus_return_val_if_fail (connection != NULL, FALSE);
_dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
-
+
CONNECTION_LOCK (connection);
- if (!_dbus_transport_get_is_authenticated (connection->transport))
+ if (!_dbus_transport_try_to_authenticate (connection->transport))
result = FALSE;
else
result = _dbus_transport_get_windows_user (connection->transport,
* result in disconnecting the connection.
*
* @param connection a #DBusConnection
- * @param size maximum message unix fds the connection can receive
+ * @param n maximum message unix fds the connection can receive
*/
void
dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
* The semantics are analogous to those of dbus_connection_set_max_received_size().
*
* @param connection the connection
- * @param size the maximum size in bytes of all outstanding messages
+ * @param n the maximum size in bytes of all outstanding messages
*/
void
dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
return res;
}
-#ifdef DBUS_BUILD_TESTS
/**
* Returns the address of the transport object of this connection
*
{
return _dbus_transport_get_address (connection->transport);
}
+
+#ifdef ENABLE_KDBUS_TRANSPORT
+DBusTransport*
+dbus_connection_get_transport(DBusConnection *connection)
+{
+ _dbus_return_val_if_fail (connection != NULL, NULL);
+
+ return connection->transport;
+}
#endif
/** @} */