]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Linux now uses recvmsg_alloc as well, reducing duplicated code.
authorRoy Marples <roy@marples.name>
Thu, 1 Sep 2016 17:01:26 +0000 (17:01 +0000)
committerRoy Marples <roy@marples.name>
Thu, 1 Sep 2016 17:01:26 +0000 (17:01 +0000)
common.c
if-linux.c

index 59d11371bdce544b54c863ae9c08d0d5c470f906..a0b1be14280b5c1a8f554bc7b502090f8db6672b 100644 (file)
--- a/common.c
+++ b/common.c
@@ -402,7 +402,7 @@ recvmsg_alloc(int fd, struct msghdr *msg)
                msg->msg_iovlen = 1;
 
        for (;;) {
-               msg->msg_flags = 0;
+               msg->msg_flags &= ~MSG_TRUNC;
                if ((bytes = recvmsg(fd, msg, MSG_PEEK | MSG_TRUNC)) == -1)
                        return -1;
                if (!(msg->msg_flags & MSG_TRUNC))
index 26018ba535b1551122e0bde786a3457ca55112ab..9d37919399bdf8682641138e5e992dd4440b8ff1 100644 (file)
@@ -337,72 +337,44 @@ static int
 get_netlink(struct dhcpcd_ctx *ctx, struct interface *ifp, int fd, int flags,
     int (*callback)(struct dhcpcd_ctx *, struct interface *, struct nlmsghdr *))
 {
-       char *buf = NULL, *nbuf;
+       struct msghdr msg;
+       struct sockaddr_nl nladdr;
        ssize_t bytes;
-       size_t buflen;
        struct nlmsghdr *nlm;
-       struct sockaddr_nl nladdr;
-       socklen_t nladdr_len;
        int r;
 
-       buflen = 0;
-       r = -1;
-       for (;;) {
-               bytes = recv(fd, NULL, 0,
-                   flags | MSG_PEEK | MSG_DONTWAIT | MSG_TRUNC);
-               if (bytes == -1)
-                       goto eexit;
-               if ((size_t)bytes == buflen) {
-                       /* Support kernels older than 2.6.22 */
-                       if (bytes == 0)
-                               bytes = 512;
-                       else
-                               bytes *= 2;
-               }
-               if (buflen < (size_t)bytes) {
-                       /* Alloc 1 more so we work with older kernels */
-                       buflen = (size_t)bytes + 1;
-                       nbuf = realloc(buf, buflen);
-                       if (nbuf == NULL)
-                               goto eexit;
-                       buf = nbuf;
-               }
-               nladdr.nl_pid = 0; /* XXX clang static analyzer bug? */
-               nladdr_len = sizeof(nladdr);
-               bytes = recvfrom(fd, buf, buflen, flags,
-                   (struct sockaddr *)&nladdr, &nladdr_len);
-               if (bytes == -1 || bytes == 0)
-                       goto eexit;
+       memset(&msg, 0, sizeof(msg));
+       msg.msg_flags = flags;
+       msg.msg_name = &nladdr;
+       msg.msg_namelen = sizeof(nladdr);
+       memset(&nladdr, 0, sizeof(nladdr));
+       msg.msg_iov = &ctx->iov;
+       if ((bytes = recvmsg_alloc(fd, &msg)) == -1)
+               return -1;
 
-               /* Check sender */
-               if (nladdr_len != sizeof(nladdr)) {
-                       errno = EINVAL;
-                       goto eexit;
-               }
-               /* Ignore message if it is not from kernel */
-               if (nladdr.nl_pid != 0) {
-                       r = 0;
-                       continue;
-               }
+       /* Check sender */
+       if (msg.msg_namelen != sizeof(nladdr)) {
+               errno = EINVAL;
+               return -1;
+       }
+       /* Ignore message if it is not from kernel */
+       if (nladdr.nl_pid != 0)
+               return 0;
 
-               for (nlm = (void *)buf;
-                    nlm && NLMSG_OK(nlm, (size_t)bytes);
-                    nlm = NLMSG_NEXT(nlm, bytes))
-               {
-                       r = err_netlink(nlm);
-                       if (r == -1)
-                               goto eexit;
-
-                       if (r == 0 && callback) {
-                               r = callback(ctx, ifp, nlm);
-                               if (r != 0)
-                                       goto eexit;
-                       }
+       r = 0;
+       for (nlm = ctx->iov.iov_base;
+            nlm && NLMSG_OK(nlm, (size_t)bytes);
+            nlm = NLMSG_NEXT(nlm, bytes))
+       {
+               if ((r = err_netlink(nlm)) == -1)
+                       return -1;
+               if (r == 0 && callback) {
+                       r = callback(ctx, ifp, nlm);
+                       if (r != 0)
+                               return r;
                }
        }
 
-eexit:
-       free(buf);
        return r;
 }