]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/libsystemd/sd-netlink/netlink-socket.c
Merge pull request #11827 from keszybz/pkgconfig-variables
[thirdparty/systemd.git] / src / libsystemd / sd-netlink / netlink-socket.c
index 590fc53fc78cf02c0bc5ce4598518e550de6da3e..432e8e8c06c9b93529751445a58d1678e47bb521 100644 (file)
@@ -1,21 +1,4 @@
-/***
-  This file is part of systemd.
-
-  Copyright 2013 Tom Gundersen <teg@jklm.no>
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include <netinet/in.h>
 #include <stdbool.h>
@@ -24,7 +7,9 @@
 #include "sd-netlink.h"
 
 #include "alloc-util.h"
-#include "formats-util.h"
+#include "fd-util.h"
+#include "format-util.h"
+#include "io-util.h"
 #include "missing.h"
 #include "netlink-internal.h"
 #include "netlink-types.h"
@@ -40,7 +25,7 @@ int socket_open(int family) {
         if (fd < 0)
                 return -errno;
 
-        return fd;
+        return fd_move_above_stdio(fd);
 }
 
 static int broadcast_groups_get(sd_netlink *nl) {
@@ -82,7 +67,7 @@ static int broadcast_groups_get(sd_netlink *nl) {
                 return r;
 
         for (i = 0; i < len; i++) {
-                for (j = 0; j < sizeof(uint32_t) * 8; j ++) {
+                for (j = 0; j < sizeof(uint32_t) * 8; j++) {
                         uint32_t offset;
                         unsigned group;
 
@@ -104,11 +89,11 @@ static int broadcast_groups_get(sd_netlink *nl) {
 
 int socket_bind(sd_netlink *nl) {
         socklen_t addrlen;
-        int r, one = 1;
+        int r;
 
-        r = setsockopt(nl->fd, SOL_NETLINK, NETLINK_PKTINFO, &one, sizeof(one));
+        r = setsockopt_int(nl->fd, SOL_NETLINK, NETLINK_PKTINFO, true);
         if (r < 0)
-                return -errno;
+                return r;
 
         addrlen = sizeof(nl->sockaddr);
 
@@ -168,7 +153,7 @@ int socket_broadcast_group_ref(sd_netlink *nl, unsigned group) {
 
         n_ref = broadcast_group_get_ref(nl, group);
 
-        n_ref ++;
+        n_ref++;
 
         r = hashmap_ensure_allocated(&nl->broadcast_group_refs, NULL);
         if (r < 0)
@@ -216,7 +201,7 @@ int socket_broadcast_group_unref(sd_netlink *nl, unsigned group) {
 
         assert(n_ref > 0);
 
-        n_ref --;
+        n_ref--;
 
         r = broadcast_group_set_ref(nl, group, n_ref);
         if (r < 0)
@@ -268,20 +253,20 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
         };
         struct cmsghdr *cmsg;
         uint32_t group = 0;
-        int r;
+        ssize_t n;
 
         assert(fd >= 0);
         assert(iov);
 
-        r = recvmsg(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0));
-        if (r < 0) {
+        n = recvmsg(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0));
+        if (n < 0) {
                 /* no data */
                 if (errno == ENOBUFS)
                         log_debug("rtnl: kernel receive buffer overrun");
                 else if (errno == EAGAIN)
                         log_debug("rtnl: no data in socket");
 
-                return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
+                return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno;
         }
 
         if (sender.nl.nl_pid != 0) {
@@ -290,9 +275,9 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
 
                 if (peek) {
                         /* drop the message */
-                        r = recvmsg(fd, &msg, 0);
-                        if (r < 0)
-                                return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
+                        n = recvmsg(fd, &msg, 0);
+                        if (n < 0)
+                                return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno;
                 }
 
                 return 0;
@@ -312,7 +297,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
         if (_group)
                 *_group = group;
 
-        return r;
+        return (int) n;
 }
 
 /* On success, the number of bytes received is returned and *ret points to the received message
@@ -329,17 +314,20 @@ int socket_read_message(sd_netlink *rtnl) {
         size_t len;
         int r;
         unsigned i = 0;
+        const NLTypeSystem *type_system_root;
 
         assert(rtnl);
         assert(rtnl->rbuffer);
         assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));
 
+        type_system_root = type_system_get_root(rtnl->protocol);
+
         /* read nothing, just get the pending message size */
         r = socket_recv_message(rtnl->fd, &iov, NULL, true);
         if (r <= 0)
                 return r;
         else
-                len = (size_t)r;
+                len = (size_t) r;
 
         /* make room for the pending message */
         if (!greedy_realloc((void **)&rtnl->rbuffer,
@@ -347,15 +335,14 @@ int socket_read_message(sd_netlink *rtnl) {
                             len, sizeof(uint8_t)))
                 return -ENOMEM;
 
-        iov.iov_base = rtnl->rbuffer;
-        iov.iov_len = rtnl->rbuffer_allocated;
+        iov = IOVEC_MAKE(rtnl->rbuffer, rtnl->rbuffer_allocated);
 
         /* read the pending message */
         r = socket_recv_message(rtnl->fd, &iov, &group, false);
         if (r <= 0)
                 return r;
         else
-                len = (size_t)r;
+                len = (size_t) r;
 
         if (len > rtnl->rbuffer_allocated)
                 /* message did not fit in read buffer */
@@ -395,7 +382,7 @@ int socket_read_message(sd_netlink *rtnl) {
                 }
 
                 /* check that we support this message type */
-                r = type_system_get_type(&type_system_root, &nl_type, new_msg->nlmsg_type);
+                r = type_system_get_type(type_system_root, &nl_type, new_msg->nlmsg_type);
                 if (r < 0) {
                         if (r == -EOPNOTSUPP)
                                 log_debug("sd-netlink: ignored message with unknown type: %i",
@@ -428,11 +415,10 @@ int socket_read_message(sd_netlink *rtnl) {
                 /* push the message onto the multi-part message stack */
                 if (first)
                         m->next = first;
-                first = m;
-                m = NULL;
+                first = TAKE_PTR(m);
         }
 
-        if (len)
+        if (len > 0)
                 log_debug("sd-netlink: discarding %zu bytes of incoming message", len);
 
         if (!first)
@@ -444,30 +430,28 @@ int socket_read_message(sd_netlink *rtnl) {
                 if (r < 0)
                         return r;
 
-                rtnl->rqueue[rtnl->rqueue_size ++] = first;
-                first = NULL;
+                rtnl->rqueue[rtnl->rqueue_size++] = TAKE_PTR(first);
 
                 if (multi_part && (i < rtnl->rqueue_partial_size)) {
                         /* remove the message form the partial read queue */
                         memmove(rtnl->rqueue_partial + i,rtnl->rqueue_partial + i + 1,
                                 sizeof(sd_netlink_message*) * (rtnl->rqueue_partial_size - i - 1));
-                        rtnl->rqueue_partial_size --;
+                        rtnl->rqueue_partial_size--;
                 }
 
                 return 1;
         } else {
                 /* we only got a partial multi-part message, push it on the
                    partial read queue */
-                if (i < rtnl->rqueue_partial_size) {
-                        rtnl->rqueue_partial[i] = first;
-                else {
+                if (i < rtnl->rqueue_partial_size)
+                        rtnl->rqueue_partial[i] = TAKE_PTR(first);
+                else {
                         r = rtnl_rqueue_partial_make_room(rtnl);
                         if (r < 0)
                                 return r;
 
-                        rtnl->rqueue_partial[rtnl->rqueue_partial_size ++] = first;
+                        rtnl->rqueue_partial[rtnl->rqueue_partial_size++] = TAKE_PTR(first);
                 }
-                first = NULL;
 
                 return 0;
         }