CMakeLists.txt: bump minimum cmake version
[project/ubus.git] / ubusd_monitor.c
index fcbc6a4b10c0199ac30ef545fea66cdf533e00eb..bba741e86987172197583331f13d8cc10e09036c 100644 (file)
@@ -29,7 +29,7 @@ ubusd_monitor_free(struct ubus_monitor *m)
        free(m);
 }
 
-static void
+static bool
 ubusd_monitor_connect(struct ubus_client *cl, struct ubus_msg_buf *ub)
 {
        struct ubus_monitor *m;
@@ -37,22 +37,40 @@ ubusd_monitor_connect(struct ubus_client *cl, struct ubus_msg_buf *ub)
        ubusd_monitor_disconnect(cl);
 
        m = calloc(1, sizeof(*m));
+       if (!m)
+               return false;
+
        m->cl = cl;
-       list_add(&m->list, &monitors);
+       list_add_tail(&m->list, &monitors);
+
+       return true;
 }
 
-void
-ubusd_monitor_disconnect(struct ubus_client *cl)
+static struct ubus_monitor*
+ubusd_monitor_find(struct ubus_client *cl)
 {
-       struct ubus_monitor *m;
+       struct ubus_monitor *m, *tmp;
 
-       list_for_each_entry(m, &monitors, list) {
+       list_for_each_entry_safe(m, tmp, &monitors, list) {
                if (m->cl != cl)
                        continue;
 
-               ubusd_monitor_free(m);
-               return;
+               return m;
        }
+
+       return NULL;
+}
+
+void
+ubusd_monitor_disconnect(struct ubus_client *cl)
+{
+       struct ubus_monitor *m;
+
+       m = ubusd_monitor_find(cl);
+       if (!m)
+               return;
+
+       ubusd_monitor_free(m);
 }
 
 void
@@ -92,13 +110,15 @@ ubusd_monitor_recv(struct ubus_client *cl, struct ubus_msg_buf *ub,
                return UBUS_STATUS_PERMISSION_DENIED;
 
        if (!strcmp(method, "add")) {
-               ubusd_monitor_connect(cl, ub);
-               return 0;
+               if (!ubusd_monitor_connect(cl, ub))
+                       return UBUS_STATUS_UNKNOWN_ERROR;
+
+               return UBUS_STATUS_OK;
        }
 
        if (!strcmp(method, "remove")) {
                ubusd_monitor_disconnect(cl);
-               return 0;
+               return UBUS_STATUS_OK;
        }
 
        return UBUS_STATUS_METHOD_NOT_FOUND;