support NameAcquired & NameLost signal subscription
[platform/upstream/dbus.git] / dbus / kdbus-common.c
old mode 100644 (file)
new mode 100755 (executable)
index ad94ea9..e1b97f9
@@ -550,20 +550,24 @@ _kdbus_free_cmd_match (struct kdbus_cmd_match *cmd)
 }
 
 int
-_kdbus_add_match_name_change (kdbus_t *kdbus,
-                              __u64    flags,
-                              __u64    cookie,
-                              __u64    old_id,
-                              __u64    old_id_flags,
-                              __u64    new_id,
-                              __u64    new_id_flags)
+_kdbus_add_match_name_acquired (kdbus_t *kdbus,
+                            __u64    flags,
+                            __u64    cookie,
+                            __u64    old_id,
+                            __u64    old_id_flags,
+                            __u64    new_id,
+                            __u64    new_id_flags,
+                            const char *name)
 {
   struct kdbus_cmd_match *cmd;
   struct kdbus_item *item;
   int ret;
+  unsigned int len = 0;
 
+  if (name)
+    len = strlen(name) + 1;
   cmd = _kdbus_new_cmd_match (kdbus,
-                              KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_name_change)),
+                              KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_name_change) + len),
                               flags,
                               cookie);
   if (NULL == cmd)
@@ -573,61 +577,177 @@ _kdbus_add_match_name_change (kdbus_t *kdbus,
   _kdbus_item_add_name_change (item,
                                old_id, old_id_flags,
                                new_id, new_id_flags);
+  item->size += len;
+  if (name)
+    memcpy(item->name_change.name, name, len);
 
   ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
-  if (0 == ret)
-    {
-      item->type = KDBUS_ITEM_NAME_ADD;
-      ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
-      if (0 == ret)
-        {
-          item->type = KDBUS_ITEM_NAME_REMOVE;
-          ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
-        }
-    }
+  if (ret != 0)
+    goto err_name_acquired;
 
+  item->type = KDBUS_ITEM_NAME_ADD;
+  ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+  if (ret != 0)
+    goto err_name_acquired;
+
+err_name_acquired:
   if (0 != ret)
     ret = errno;
-
   _kdbus_free_cmd_match (cmd);
   return ret;
 }
 
 int
-_kdbus_add_match_id_change (kdbus_t *kdbus,
+_kdbus_add_match_name_lost (kdbus_t *kdbus,
                             __u64    flags,
                             __u64    cookie,
-                            __u64    id,
-                            __u64    id_flags)
+                            __u64    old_id,
+                            __u64    old_id_flags,
+                            __u64    new_id,
+                            __u64    new_id_flags,
+                            const char *name)
 {
   struct kdbus_cmd_match *cmd;
   struct kdbus_item *item;
   int ret;
+  unsigned int len = 0;
+
+  if (name)
+    len = strlen(name) + 1;
 
   cmd = _kdbus_new_cmd_match (kdbus,
-                              KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_id_change)),
+                              KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_name_change) + len),
                               flags,
                               cookie);
   if (NULL == cmd)
     return ENOMEM;
 
   item = cmd->items;
-  _kdbus_item_add_id_add (item, id, id_flags);
+  _kdbus_item_add_name_change (item,
+                               old_id, old_id_flags,
+                               new_id, new_id_flags);
+
+  item->size += len;
+  if (name)
+  memcpy(item->name_change.name, name, len);
 
   ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
-  if (0 == ret)
-    {
-      item->type = KDBUS_ITEM_ID_REMOVE;
-      ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
-    }
+  if (ret != 0)
+    goto err_name_remove;
+
+  item->type = KDBUS_ITEM_NAME_REMOVE;
+  ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+  if (ret != 0)
+    goto err_name_remove;
 
+err_name_remove:
   if (0 != ret)
     ret = errno;
-
   _kdbus_free_cmd_match (cmd);
   return ret;
 }
 
+int
+_kdbus_add_match_name_change (kdbus_t *kdbus,
+                              __u64    flags,
+                              __u64    cookie,
+                              __u64    old_id,
+                              __u64    old_id_flags,
+                              __u64    new_id,
+                              __u64    new_id_flags,
+                              const char *name)
+{
+  struct kdbus_cmd_match *cmd;
+  struct kdbus_item *item;
+  int ret;
+  unsigned int len = 0;
+
+  if (name)
+   len = strlen(name) + 1;
+
+  /* name = NULL or Well-known Name */
+  if (name == NULL || (name[0] != ':' && _dbus_validate_bus_name (&name, 0, _dbus_string_get_length (&name)))) {
+    cmd = _kdbus_new_cmd_match (kdbus,
+                                KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_name_change) + len),
+                                flags,
+                                cookie);
+    if (NULL == cmd)
+      return ENOMEM;
+
+    item = cmd->items;
+    _kdbus_item_add_name_change (item,
+                                 old_id, old_id_flags,
+                                 new_id, new_id_flags);
+
+    item->size += len;
+    if (name)
+      memcpy(item->name_change.name, name, len);
+
+    ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+    if (0 == ret)
+      {
+        item->type = KDBUS_ITEM_NAME_ADD;
+        ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+        if (0 == ret)
+          {
+           item->type = KDBUS_ITEM_NAME_REMOVE;
+           ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+          }
+      }
+
+    if (0 != ret)
+      ret = errno;
+
+    _kdbus_free_cmd_match (cmd);
+    return ret;
+  }
+
+  return FALSE;
+}
+
+int
+_kdbus_add_match_id_change (kdbus_t *kdbus,
+                            __u64    flags,
+                            __u64    cookie,
+                            __u64    id,
+                            __u64    id_flags,
+                            const char *name)
+{
+  struct kdbus_cmd_match *cmd;
+  struct kdbus_item *item;
+  int ret;
+
+  /* name = NULL or Unique Name */
+  if (name == NULL || (name[0] == ':' && _dbus_validate_bus_name (&name, 0, _dbus_string_get_length (&name)))) {
+    cmd = _kdbus_new_cmd_match (kdbus,
+                                KDBUS_ITEM_SIZE (sizeof (struct kdbus_notify_id_change)),
+                                flags,
+                                cookie);
+    if (NULL == cmd)
+      return ENOMEM;
+
+    item = cmd->items;
+    _kdbus_item_add_id_add (item, id, id_flags);
+
+    if (name)
+      item->id_change.id = strtoull (name + 3, NULL, 10);
+
+    ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+    if (0 == ret)
+      {
+        item->type = KDBUS_ITEM_ID_REMOVE;
+        ret = safe_ioctl (kdbus->fd, KDBUS_CMD_MATCH_ADD, cmd);
+      }
+
+   if (0 != ret)
+     ret = errno;
+
+    _kdbus_free_cmd_match (cmd);
+    return ret;
+  }
+  return FALSE;
+}
+
 int _kdbus_add_match (kdbus_t *kdbus,
                       struct kdbus_cmd_match *cmd)
 {