[kdbus][wip] Add matches for kernel notifications

This commit is contained in:
Lukasz Skalski
2014-10-27 13:05:08 +00:00
committed by Ryan Lortie
parent 9141fc1668
commit f2cdea88c8
3 changed files with 155 additions and 0 deletions

View File

@@ -3990,6 +3990,16 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
{
if (!is_signal_data_for_name_lost_or_acquired (signal_data))
add_match_rule (connection, signal_data->rule);
else
{
if (G_IS_KDBUS_CONNECTION (connection->stream))
{
if (g_strcmp0 (signal_data->member, "NameAcquired") == 0)
_g_kdbus_subscribe_name_acquired (connection, arg0);
else if (g_strcmp0 (signal_data->member, "NameLost") == 0)
_g_kdbus_subscribe_name_lost (connection, arg0);
}
}
}
signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array,
@@ -4076,6 +4086,13 @@ unsubscribe_id_internal (GDBusConnection *connection,
*/
remove_match_rule (connection, signal_data->rule);
}
else
{
if (G_IS_KDBUS_CONNECTION (connection->stream))
{
//_g_kdbus_unsubscribe_name_lost_and_acquired (connection, arg0);
}
}
signal_data_free (signal_data);
}

View File

@@ -1252,6 +1252,138 @@ _g_kdbus_GetConnectionUnixUser (GDBusConnection *connection,
}
/*
* _g_kdbus_subscribe_name_acquired:
*
*/
static void
_g_kdbus_subscribe_name_owner_changed (GDBusConnection *connection,
const gchar *name,
const gchar *old_name,
const gchar *new_name)
{
GKdbus *kdbus;
struct kdbus_item *item;
struct kdbus_cmd_match *cmd_match;
gssize size, len;
gint ret;
guint64 old_id = KDBUS_MATCH_ID_ANY;
guint64 new_id = KDBUS_MATCH_ID_ANY;
kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
len = strlen(name) + 1;
size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
G_STRUCT_OFFSET (struct kdbus_item, name_change) +
G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
cmd_match = g_alloca0 (size);
cmd_match->size = size;
cmd_match->cookie = 1000;
item = cmd_match->items;
/* KDBUS_ITEM_NAME_CHANGE */
item->type = KDBUS_ITEM_NAME_CHANGE;
item->name_change.old_id.id = old_id;
item->name_change.new_id.id = new_id;
memcpy(item->name_change.name, name, len);
item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
item = KDBUS_ITEM_NEXT(item);
ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
if (ret < 0)
g_warning ("ERROR - %d\n", (int) errno);
}
/*
* _g_kdbus_subscribe_name_acquired:
*
*/
void
_g_kdbus_subscribe_name_acquired (GDBusConnection *connection,
const gchar *name)
{
GKdbus *kdbus;
struct kdbus_item *item;
struct kdbus_cmd_match *cmd_match;
gssize size, len;
gint ret;
kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
len = strlen(name) + 1;
size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
G_STRUCT_OFFSET (struct kdbus_item, name_change) +
G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
cmd_match = g_alloca0 (size);
cmd_match->size = size;
cmd_match->cookie = 1001;
item = cmd_match->items;
/* KDBUS_ITEM_NAME_ADD */
item->type = KDBUS_ITEM_NAME_ADD;
item->name_change.old_id.id = KDBUS_MATCH_ID_ANY;
item->name_change.new_id.id = kdbus->priv->unique_id;
memcpy(item->name_change.name, name, len);
item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
item = KDBUS_ITEM_NEXT(item);
ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
if (ret < 0)
g_warning ("ERROR - %d\n", (int) errno);
_g_kdbus_subscribe_name_owner_changed (connection, name, "test", "test");
}
/*
* _g_kdbus_subscribe_name_lost:
*
*/
void
_g_kdbus_subscribe_name_lost (GDBusConnection *connection,
const gchar *name)
{
GKdbus *kdbus;
struct kdbus_item *item;
struct kdbus_cmd_match *cmd_match;
gssize size, len;
gint ret;
kdbus = _g_kdbus_connection_get_kdbus (G_KDBUS_CONNECTION (g_dbus_connection_get_stream (connection)));
len = strlen(name) + 1;
size = KDBUS_ALIGN8(G_STRUCT_OFFSET (struct kdbus_cmd_match, items) +
G_STRUCT_OFFSET (struct kdbus_item, name_change) +
G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len);
cmd_match = g_alloca0 (size);
cmd_match->size = size;
cmd_match->cookie = 1002;
item = cmd_match->items;
/* KDBUS_ITEM_NAME_REMOVE */
item->type = KDBUS_ITEM_NAME_REMOVE;
item->name_change.old_id.id = kdbus->priv->unique_id;
item->name_change.new_id.id = KDBUS_MATCH_ID_ANY;
memcpy(item->name_change.name, name, len);
item->size = G_STRUCT_OFFSET (struct kdbus_item, name_change) +
G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len;
item = KDBUS_ITEM_NEXT(item);
ret = ioctl(kdbus->priv->fd, KDBUS_CMD_MATCH_ADD, cmd_match);
if (ret < 0)
g_warning ("ERROR - %d\n", (int) errno);
_g_kdbus_subscribe_name_owner_changed (connection, name, "test", "test");
}
/**
* g_kdbus_decode_kernel_msg:
*

View File

@@ -109,6 +109,12 @@ GVariant * _g_kdbus_GetConnectionUnixUser (GDB
const gchar *name,
GError **error);
void _g_kdbus_subscribe_name_acquired (GDBusConnection *connection,
const gchar *name);
void _g_kdbus_subscribe_name_lost (GDBusConnection *connection,
const gchar *name);
gssize _g_kdbus_receive (GKdbus *kdbus,
GCancellable *cancellable,
GError **error);