chiark / gitweb /
dbus: fix return value of dispatch_rqueue()
[elogind.git] / src / libsystemd-bus / sd-bus.c
index 5e66a31162611ac2d7ae988840aa55950a458320..db0880f21ce7c2ea3d987676ef9781af6a15249f 100644 (file)
@@ -125,7 +125,7 @@ int sd_bus_new(sd_bus **ret) {
         r->n_ref = REFCNT_INIT;
         r->input_fd = r->output_fd = -1;
         r->message_version = 1;
-        r->negotiate_fds = true;
+        r->hello_flags |= KDBUS_HELLO_ACCEPT_FD;
         r->original_pid = getpid();
 
         assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0);
@@ -226,7 +226,7 @@ int sd_bus_set_bus_client(sd_bus *bus, int b) {
         return 0;
 }
 
-int sd_bus_set_negotiate_fds(sd_bus *bus, int b) {
+int sd_bus_negotiate_fds(sd_bus *bus, int b) {
         if (!bus)
                 return -EINVAL;
         if (bus->state != BUS_UNSET)
@@ -234,7 +234,91 @@ int sd_bus_set_negotiate_fds(sd_bus *bus, int b) {
         if (bus_pid_changed(bus))
                 return -ECHILD;
 
-        bus->negotiate_fds = !!b;
+        SET_FLAG(bus->hello_flags, KDBUS_HELLO_ACCEPT_FD, b);
+        return 0;
+}
+
+int sd_bus_negotiate_attach_comm(sd_bus *bus, int b) {
+        if (!bus)
+                return -EINVAL;
+        if (bus->state != BUS_UNSET)
+                return -EPERM;
+        if (bus_pid_changed(bus))
+                return -ECHILD;
+
+        SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_COMM, b);
+        return 0;
+}
+
+int sd_bus_negotiate_attach_exe(sd_bus *bus, int b) {
+        if (!bus)
+                return -EINVAL;
+        if (bus->state != BUS_UNSET)
+                return -EPERM;
+        if (bus_pid_changed(bus))
+                return -ECHILD;
+
+        SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_EXE, b);
+        return 0;
+}
+
+int sd_bus_negotiate_attach_cmdline(sd_bus *bus, int b) {
+        if (!bus)
+                return -EINVAL;
+        if (bus->state != BUS_UNSET)
+                return -EPERM;
+        if (bus_pid_changed(bus))
+                return -ECHILD;
+
+        SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CMDLINE, b);
+        return 0;
+}
+
+int sd_bus_negotiate_attach_cgroup(sd_bus *bus, int b) {
+        if (!bus)
+                return -EINVAL;
+        if (bus->state != BUS_UNSET)
+                return -EPERM;
+        if (bus_pid_changed(bus))
+                return -ECHILD;
+
+        SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CGROUP, b);
+        return 0;
+}
+
+int sd_bus_negotiate_attach_caps(sd_bus *bus, int b) {
+        if (!bus)
+                return -EINVAL;
+        if (bus->state != BUS_UNSET)
+                return -EPERM;
+        if (bus_pid_changed(bus))
+                return -ECHILD;
+
+        SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CAPS, b);
+        return 0;
+}
+
+int sd_bus_negotiate_attach_selinux_context(sd_bus *bus, int b) {
+        if (!bus)
+                return -EINVAL;
+        if (bus->state != BUS_UNSET)
+                return -EPERM;
+        if (bus_pid_changed(bus))
+                return -ECHILD;
+
+        SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_SECLABEL, b);
+        return 0;
+}
+
+int sd_bus_negotiate_attach_audit(sd_bus *bus, int b) {
+        if (!bus)
+                return -EINVAL;
+        if (bus->state != BUS_UNSET)
+                return -EPERM;
+        if (bus_pid_changed(bus))
+                return -ECHILD;
+
+        SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_AUDIT, b);
         return 0;
 }
 
@@ -1015,7 +1099,7 @@ int sd_bus_can_send(sd_bus *bus, char type) {
                 return -ECHILD;
 
         if (type == SD_BUS_TYPE_UNIX_FD) {
-                if (!bus->negotiate_fds)
+                if (!(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD))
                         return 0;
 
                 r = bus_ensure_running(bus);
@@ -1131,11 +1215,11 @@ static int dispatch_rqueue(sd_bus *bus, sd_bus_message **m) {
                 if (r == 0)
                         return ret;
 
-                r = 1;
+                ret = 1;
         } while (!z);
 
         *m = z;
-        return 1;
+        return ret;
 }
 
 int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) {
@@ -2320,6 +2404,9 @@ int sd_bus_remove_fallback(sd_bus *bus, const char *prefix, sd_bus_message_handl
 }
 
 int sd_bus_add_match(sd_bus *bus, const char *match, sd_bus_message_handler_t callback, void *userdata) {
+        struct bus_match_component *components = NULL;
+        unsigned n_components = 0;
+        uint64_t cookie = 0;
         int r = 0;
 
         if (!bus)
@@ -2329,27 +2416,35 @@ int sd_bus_add_match(sd_bus *bus, const char *match, sd_bus_message_handler_t ca
         if (bus_pid_changed(bus))
                 return -ECHILD;
 
+        r = bus_match_parse(match, &components, &n_components);
+        if (r < 0)
+                goto finish;
+
         if (bus->bus_client) {
-                r = bus_add_match_internal(bus, match);
+                cookie = ++bus->match_cookie;
+
+                r = bus_add_match_internal(bus, match, components, n_components, cookie);
                 if (r < 0)
-                        return r;
+                        goto finish;
         }
 
-        if (callback) {
-                bus->match_callbacks_modified = true;
-                r = bus_match_add(&bus->match_callbacks, match, callback, userdata, NULL);
-                if (r < 0) {
-
-                        if (bus->bus_client)
-                                bus_remove_match_internal(bus, match);
-                }
+        bus->match_callbacks_modified = true;
+        r = bus_match_add(&bus->match_callbacks, components, n_components, callback, userdata, cookie, NULL);
+        if (r < 0) {
+                if (bus->bus_client)
+                        bus_remove_match_internal(bus, match, cookie);
         }
 
+finish:
+        bus_match_parse_free(components, n_components);
         return r;
 }
 
 int sd_bus_remove_match(sd_bus *bus, const char *match, sd_bus_message_handler_t callback, void *userdata) {
+        struct bus_match_component *components = NULL;
+        unsigned n_components = 0;
         int r = 0, q = 0;
+        uint64_t cookie = 0;
 
         if (!bus)
                 return -EINVAL;
@@ -2358,17 +2453,19 @@ int sd_bus_remove_match(sd_bus *bus, const char *match, sd_bus_message_handler_t
         if (bus_pid_changed(bus))
                 return -ECHILD;
 
+        r = bus_match_parse(match, &components, &n_components);
+        if (r < 0)
+                return r;
+
+        bus->match_callbacks_modified = true;
+        r = bus_match_remove(&bus->match_callbacks, components, n_components, callback, userdata, &cookie);
+
         if (bus->bus_client)
-                r = bus_remove_match_internal(bus, match);
+                q = bus_remove_match_internal(bus, match, cookie);
 
-        if (callback) {
-                bus->match_callbacks_modified = true;
-                q = bus_match_remove(&bus->match_callbacks, match, callback, userdata);
-        }
+        bus_match_parse_free(components, n_components);
 
-        if (r < 0)
-                return r;
-        return q;
+        return r < 0 ? r : q;
 }
 
 int sd_bus_emit_signal(
@@ -2417,6 +2514,7 @@ int sd_bus_call_method(
         int r;
 
         if (!bus)
+
                 return -EINVAL;
         if (!BUS_IS_OPEN(bus->state))
                 return -ENOTCONN;