]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: handle -EINTR returned from fd_wait_for_event() better
authorLennart Poettering <lennart@poettering.net>
Tue, 22 Nov 2022 11:28:19 +0000 (12:28 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 22 Nov 2022 12:09:17 +0000 (13:09 +0100)
We might get signals for various reasons (for example, somebody asking
us to reload caches via a signal), hence let's handle this gracefully.

src/resolve/resolved-manager.c

index f62efa87aac7487f4aa13b3bc2cfb6c548ff0d43..1c9048670bf0e4cede5fe03ab85e88e1c775f0f6 100644 (file)
@@ -868,11 +868,14 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
 }
 
 static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
+        usec_t end;
         int r;
 
         assert(fd >= 0);
         assert(mh);
 
+        end = usec_add(now(CLOCK_MONOTONIC), SEND_TIMEOUT_USEC);
+
         for (;;) {
                 if (sendmsg(fd, mh, flags) >= 0)
                         return 0;
@@ -881,20 +884,26 @@ static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
                 if (errno != EAGAIN)
                         return -errno;
 
-                r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
-                if (r < 0)
+                r = fd_wait_for_event(fd, POLLOUT, LESS_BY(end, now(CLOCK_MONOTONIC)));
+                if (r < 0) {
+                        if (ERRNO_IS_TRANSIENT(r))
+                                continue;
                         return r;
+                }
                 if (r == 0)
                         return -ETIMEDOUT;
         }
 }
 
 static int write_loop(int fd, void *message, size_t length) {
+        usec_t end;
         int r;
 
         assert(fd >= 0);
         assert(message);
 
+        end = usec_add(now(CLOCK_MONOTONIC), SEND_TIMEOUT_USEC);
+
         for (;;) {
                 if (write(fd, message, length) >= 0)
                         return 0;
@@ -903,9 +912,12 @@ static int write_loop(int fd, void *message, size_t length) {
                 if (errno != EAGAIN)
                         return -errno;
 
-                r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
-                if (r < 0)
+                r = fd_wait_for_event(fd, POLLOUT, LESS_BY(end, now(CLOCK_MONOTONIC)));
+                if (r < 0) {
+                        if (ERRNO_IS_TRANSIENT(r))
+                                continue;
                         return r;
+                }
                 if (r == 0)
                         return -ETIMEDOUT;
         }