ubusd: retry sending messages on EINTR
authorFelix Fietkau <nbd@nbd.name>
Tue, 16 Apr 2019 09:13:44 +0000 (11:13 +0200)
committerFelix Fietkau <nbd@nbd.name>
Tue, 23 Apr 2019 07:40:30 +0000 (09:40 +0200)
Avoids unnecessary delays and/or blocking on messages

Signed-off-by: Felix Fietkau <nbd@nbd.name>
ubusd.c

diff --git a/ubusd.c b/ubusd.c
index ba1ff07720fa3da7cf5576eecfddc1c9530ba391..0f35d3e25d344ea36a3a867ef19370790e715d71 100644 (file)
--- a/ubusd.c
+++ b/ubusd.c
@@ -109,16 +109,16 @@ static int ubus_msg_writev(int fd, struct ubus_msg_buf *ub, int offset)
                .msg_control = &fd_buf,
                .msg_controllen = sizeof(fd_buf),
        };
+       struct ubus_msghdr hdr;
+       int ret;
 
        fd_buf.fd = ub->fd;
-       if (ub->fd < 0) {
+       if (ub->fd < 0 || offset) {
                msghdr.msg_control = NULL;
                msghdr.msg_controllen = 0;
        }
 
        if (offset < sizeof(ub->hdr)) {
-               struct ubus_msghdr hdr;
-
                hdr.version = ub->hdr.version;
                hdr.type = ub->hdr.type;
                hdr.seq = cpu_to_be16(ub->hdr.seq);
@@ -128,12 +128,18 @@ static int ubus_msg_writev(int fd, struct ubus_msg_buf *ub, int offset)
                iov[0].iov_len = sizeof(hdr) - offset;
                iov[1].iov_base = (char *) ub->data;
                iov[1].iov_len = ub->len;
-
-               return sendmsg(fd, &msghdr, 0);
        } else {
                offset -= sizeof(ub->hdr);
-               return write(fd, ((char *) ub->data) + offset, ub->len - offset);
+               iov[0].iov_base = ((char *) ub->data) + offset;
+               iov[0].iov_len = ub->len - offset;
+               msghdr.msg_iovlen = 1;
        }
+
+       do {
+               ret = sendmsg(fd, &msghdr, 0);
+       } while (ret < 0 && errno == EINTR);
+
+       return ret;
 }
 
 static void ubus_msg_enqueue(struct ubus_client *cl, struct ubus_msg_buf *ub)