]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/varlink.c
varlink: add varlink server to event loop only if there is one
[thirdparty/systemd.git] / src / shared / varlink.c
index 3596bd2c8766f6d5697da31b3617077e585d7295..54d48991e855a6e2af209fdca76ac368f3d95de2 100644 (file)
@@ -228,10 +228,15 @@ static inline const char *varlink_server_description(VarlinkServer *s) {
 
 static void varlink_set_state(Varlink *v, VarlinkState state) {
         assert(v);
+        assert(state >= 0 && state < _VARLINK_STATE_MAX);
 
-        varlink_log(v, "varlink: changing state %s → %s",
-                  varlink_state_to_string(v->state),
-                  varlink_state_to_string(state));
+        if (v->state < 0)
+                varlink_log(v, "varlink: setting state %s",
+                            varlink_state_to_string(state));
+        else
+                varlink_log(v, "varlink: changing state %s → %s",
+                            varlink_state_to_string(v->state),
+                            varlink_state_to_string(state));
 
         v->state = state;
 }
@@ -335,25 +340,13 @@ int varlink_connect_fd(Varlink **ret, int fd) {
 static void varlink_detach_event_sources(Varlink *v) {
         assert(v);
 
-        if (v->io_event_source) {
-                (void) sd_event_source_set_enabled(v->io_event_source, SD_EVENT_OFF);
-                v->io_event_source = sd_event_source_unref(v->io_event_source);
-        }
+        v->io_event_source = sd_event_source_disable_unref(v->io_event_source);
 
-        if (v->time_event_source) {
-                (void) sd_event_source_set_enabled(v->time_event_source, SD_EVENT_OFF);
-                v->time_event_source = sd_event_source_unref(v->time_event_source);
-        }
+        v->time_event_source = sd_event_source_disable_unref(v->time_event_source);
 
-        if (v->quit_event_source) {
-                (void) sd_event_source_set_enabled(v->quit_event_source, SD_EVENT_OFF);
-                v->quit_event_source = sd_event_source_unref(v->quit_event_source);
-        }
+        v->quit_event_source = sd_event_source_disable_unref(v->quit_event_source);
 
-        if (v->defer_event_source) {
-                (void) sd_event_source_set_enabled(v->defer_event_source, SD_EVENT_OFF);
-                v->defer_event_source = sd_event_source_unref(v->defer_event_source);
-        }
+        v->defer_event_source = sd_event_source_disable_unref(v->defer_event_source);
 }
 
 static void varlink_clear(Varlink *v) {
@@ -1009,7 +1002,6 @@ int varlink_wait(Varlink *v, usec_t timeout) {
         usec_t t;
 
         assert_return(v, -EINVAL);
-        assert_return(!v->server, -ENOTTY);
 
         if (v->state == VARLINK_DISCONNECTED)
                 return -ENOTCONN;
@@ -1218,6 +1210,7 @@ static int varlink_enqueue_json(Varlink *v, JsonVariant *m) {
         r = json_variant_format(m, 0, &text);
         if (r < 0)
                 return r;
+        assert(text[r] == '\0');
 
         if (v->output_buffer_size + r + 1 > VARLINK_BUFFER_MAX)
                 return -ENOBUFS;
@@ -1241,15 +1234,16 @@ static int varlink_enqueue_json(Varlink *v, JsonVariant *m) {
 
         } else {
                 char *n;
+                const size_t new_size = v->output_buffer_size + r + 1;
 
-                n = new(char, v->output_buffer_size + r + 1);
+                n = new(char, new_size);
                 if (!n)
                         return -ENOMEM;
 
                 memcpy(mempcpy(n, v->output_buffer + v->output_buffer_index, v->output_buffer_size), text, r + 1);
 
                 free_and_replace(v->output_buffer, n);
-                v->output_buffer_size += r + 1;
+                v->output_buffer_allocated = v->output_buffer_size = new_size;
                 v->output_buffer_index = 0;
         }
 
@@ -2058,12 +2052,14 @@ int varlink_server_add_connection(VarlinkServer *server, int fd, Varlink **ret)
 
         varlink_set_state(v, VARLINK_IDLE_SERVER);
 
-        r = varlink_attach_event(v, server->event, server->event_priority);
-        if (r < 0) {
-                varlink_log_errno(v, r, "Failed to attach new connection: %m");
-                v->fd = -1; /* take the fd out of the connection again */
-                varlink_close(v);
-                return r;
+        if (server->event) {
+                r = varlink_attach_event(v, server->event, server->event_priority);
+                if (r < 0) {
+                        varlink_log_errno(v, r, "Failed to attach new connection: %m");
+                        v->fd = -1; /* take the fd out of the connection again */
+                        varlink_close(v);
+                        return r;
+                }
         }
 
         if (ret)
@@ -2203,10 +2199,7 @@ static VarlinkServerSocket* varlink_server_socket_destroy(VarlinkServerSocket *s
         if (ss->server)
                 LIST_REMOVE(sockets, ss->server->sockets, ss);
 
-        if (ss->event_source) {
-                (void) sd_event_source_set_enabled(ss->event_source, SD_EVENT_OFF);
-                sd_event_source_unref(ss->event_source);
-        }
+        sd_event_source_disable_unref(ss->event_source);
 
         free(ss->address);
         safe_close(ss->fd);
@@ -2312,7 +2305,7 @@ int varlink_server_bind_method(VarlinkServer *s, const char *method, VarlinkMeth
 
 int varlink_server_bind_method_many_internal(VarlinkServer *s, ...) {
         va_list ap;
-        int r;
+        int r = 0;
 
         assert_return(s, -EINVAL);
 
@@ -2329,10 +2322,11 @@ int varlink_server_bind_method_many_internal(VarlinkServer *s, ...) {
 
                 r = varlink_server_bind_method(s, method, callback);
                 if (r < 0)
-                        return r;
+                        break;
         }
+        va_end(ap);
 
-        return 0;
+        return r;
 }
 
 int varlink_server_bind_connect(VarlinkServer *s, VarlinkConnect callback) {