]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/varlink.c
various: use _NEG_ macros to reduce indentation
[thirdparty/systemd.git] / src / shared / varlink.c
index 808e2b2dbabf942c6fda0cf073056841e140d6f8..41c2daf02bd8d21e12338ed405a0adf8fa509839 100644 (file)
@@ -133,6 +133,9 @@ struct Varlink {
         size_t input_buffer_size;
         size_t input_buffer_unscanned;
 
+        void *input_control_buffer;
+        size_t input_control_buffer_size;
+
         char *output_buffer; /* valid data starts at output_buffer_index, ends at output_buffer_index+output_buffer_size */
         size_t output_buffer_index;
         size_t output_buffer_size;
@@ -457,6 +460,9 @@ static void varlink_clear(Varlink *v) {
         v->input_buffer = mfree(v->input_buffer);
         v->output_buffer = v->output_buffer_sensitive ? erase_and_free(v->output_buffer) : mfree(v->output_buffer);
 
+        v->input_control_buffer = mfree(v->input_control_buffer);
+        v->input_control_buffer_size = 0;
+
         varlink_clear_current(v);
 
         close_many(v->output_fds, v->n_output_fds);
@@ -633,7 +639,6 @@ static int varlink_write(Varlink *v) {
 #define VARLINK_FDS_MAX (16U*1024U)
 
 static int varlink_read(Varlink *v) {
-        CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int) * VARLINK_FDS_MAX)) control;
         struct iovec iov;
         struct msghdr mh;
         size_t rs;
@@ -686,16 +691,23 @@ static int varlink_read(Varlink *v) {
         rs = MALLOC_SIZEOF_SAFE(v->input_buffer) - (v->input_buffer_index + v->input_buffer_size);
 
         if (v->allow_fd_passing_input) {
-                iov = (struct iovec) {
-                        .iov_base = p,
-                        .iov_len = rs,
-                };
+                iov = IOVEC_MAKE(p, rs);
+
+                /* Allocate the fd buffer on the heap, since we need a lot of space potentially */
+                if (!v->input_control_buffer) {
+                        v->input_control_buffer_size = CMSG_SPACE(sizeof(int) * VARLINK_FDS_MAX);
+                        v->input_control_buffer = malloc(v->input_control_buffer_size);
+                        if (!v->input_control_buffer)
+                                return -ENOMEM;
+                }
+
                 mh = (struct msghdr) {
                         .msg_iov = &iov,
                         .msg_iovlen = 1,
-                        .msg_control = &control,
-                        .msg_controllen = sizeof(control),
+                        .msg_control = v->input_control_buffer,
+                        .msg_controllen = v->input_control_buffer_size,
                 };
+
                 n = recvmsg_safe(v->fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
         } else {
                 bool prefer_read = v->prefer_read_write;
@@ -1267,8 +1279,8 @@ int varlink_wait(Varlink *v, usec_t timeout) {
                 return events;
 
         r = fd_wait_for_event(fd, events, t);
-        if (r < 0 && ERRNO_IS_TRANSIENT(r)) /* Treat EINTR as not a timeout, but also nothing happened, and
-                                             * the caller gets a chance to call back into us */
+        if (ERRNO_IS_NEG_TRANSIENT(r)) /* Treat EINTR as not a timeout, but also nothing happened, and
+                                        * the caller gets a chance to call back into us */
                 return 1;
         if (r <= 0)
                 return r;
@@ -1356,14 +1368,11 @@ int varlink_flush(Varlink *v) {
                 }
 
                 r = fd_wait_for_event(v->fd, POLLOUT, USEC_INFINITY);
-                if (r < 0) {
-                        if (ERRNO_IS_TRANSIENT(r))
-                                continue;
-
+                if (ERRNO_IS_NEG_TRANSIENT(r))
+                        continue;
+                if (r < 0)
                         return varlink_log_errno(v, r, "Poll failed on fd: %m");
-                }
-
-                assert(r != 0);
+                assert(r > 0);
 
                 handle_revents(v, r);
         }
@@ -2750,7 +2759,7 @@ int varlink_server_listen_address(VarlinkServer *s, const char *address, mode_t
                         return r;
         }
 
-        if (listen(fd, SOMAXCONN) < 0)
+        if (listen(fd, SOMAXCONN_DELUXE) < 0)
                 return -errno;
 
         r = varlink_server_create_listen_fd_socket(s, fd, &ss);
@@ -3060,12 +3069,9 @@ int varlink_server_deserialize_one(VarlinkServer *s, const char *value, FDSet *f
         n = strcspn(v, " ");
         buf = strndupa_safe(v, n);
 
-        r = safe_atoi(buf, &fd);
-        if (r < 0)
-                return log_debug_errno(r, "Unable to parse VarlinkServerSocket varlink-server-socket-fd=%s: %m", buf);
+        fd = parse_fd(buf);
         if (fd < 0)
-                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "VarlinkServerSocket varlink-server-socket-fd= has an invalid value: %d", fd);
+                return log_debug_errno(fd, "Unable to parse VarlinkServerSocket varlink-server-socket-fd=%s: %m", buf);
         if (!fdset_contains(fds, fd))
                 return log_debug_errno(SYNTHETIC_ERRNO(EBADF),
                                        "VarlinkServerSocket varlink-server-socket-fd= has unknown fd %d: %m", fd);