ac3a84
From d56013fb245dc2878ee91bbb937a91850050ada3 Mon Sep 17 00:00:00 2001
ac3a84
From: Lennart Poettering <lennart@poettering.net>
ac3a84
Date: Mon, 21 Nov 2022 17:42:04 +0100
ac3a84
Subject: [PATCH] sd-bus: handle -EINTR return from bus_poll()
ac3a84
ac3a84
In sd_bus_wait(), let's convert EINTR to a return code of 0, thus asking
ac3a84
the caller do loop again and enter sd_bus_process() again (which will
ac3a84
not find any queued events). This way we'll not return an error on
ac3a84
something that isn't really an error. This should typically make sure
ac3a84
things are properly handled by the caller, magically, without eating up
ac3a84
the event entirely, and still giving the caller time to run some code if
ac3a84
they want.
ac3a84
ac3a84
(cherry picked from commit 3022916b4d2483452c3ddbbac9ee7c4372b1cb46)
ac3a84
ac3a84
Resolves: #2137584
ac3a84
---
ac3a84
 src/libsystemd/sd-bus/bus-socket.c |  5 ++++-
ac3a84
 src/libsystemd/sd-bus/sd-bus.c     | 18 +++++++++++++++---
ac3a84
 2 files changed, 19 insertions(+), 4 deletions(-)
ac3a84
ac3a84
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
ac3a84
index c94befef73..253f41c636 100644
ac3a84
--- a/src/libsystemd/sd-bus/bus-socket.c
ac3a84
+++ b/src/libsystemd/sd-bus/bus-socket.c
ac3a84
@@ -1308,8 +1308,11 @@ int bus_socket_process_opening(sd_bus *b) {
ac3a84
         assert(b->state == BUS_OPENING);
ac3a84
 
ac3a84
         events = fd_wait_for_event(b->output_fd, POLLOUT, 0);
ac3a84
-        if (events < 0)
ac3a84
+        if (events < 0) {
ac3a84
+                if (ERRNO_IS_TRANSIENT(events))
ac3a84
+                        return 0;
ac3a84
                 return events;
ac3a84
+        }
ac3a84
         if (!(events & (POLLOUT|POLLERR|POLLHUP)))
ac3a84
                 return 0;
ac3a84
 
ac3a84
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
ac3a84
index bc716afabf..c3a1bae295 100644
ac3a84
--- a/src/libsystemd/sd-bus/sd-bus.c
ac3a84
+++ b/src/libsystemd/sd-bus/sd-bus.c
ac3a84
@@ -2465,8 +2465,11 @@ _public_ int sd_bus_call(
ac3a84
                         left = UINT64_MAX;
ac3a84
 
ac3a84
                 r = bus_poll(bus, true, left);
ac3a84
-                if (r < 0)
ac3a84
+                if (r < 0) {
ac3a84
+                        if (ERRNO_IS_TRANSIENT(r))
ac3a84
+                                continue;
ac3a84
                         goto fail;
ac3a84
+                }
ac3a84
                 if (r == 0) {
ac3a84
                         r = -ETIMEDOUT;
ac3a84
                         goto fail;
ac3a84
@@ -3321,6 +3324,7 @@ static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
ac3a84
 }
ac3a84
 
ac3a84
 _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
ac3a84
+        int r;
ac3a84
 
ac3a84
         assert_return(bus, -EINVAL);
ac3a84
         assert_return(bus = bus_resolve(bus), -ENOPKG);
ac3a84
@@ -3335,7 +3339,11 @@ _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
ac3a84
         if (bus->rqueue_size > 0)
ac3a84
                 return 0;
ac3a84
 
ac3a84
-        return bus_poll(bus, false, timeout_usec);
ac3a84
+        r = bus_poll(bus, false, timeout_usec);
ac3a84
+        if (r < 0 && ERRNO_IS_TRANSIENT(r))
ac3a84
+                return 1; /* treat EINTR as success, but let's exit, so that the caller will call back into us soon. */
ac3a84
+
ac3a84
+        return r;
ac3a84
 }
ac3a84
 
ac3a84
 _public_ int sd_bus_flush(sd_bus *bus) {
ac3a84
@@ -3377,8 +3385,12 @@ _public_ int sd_bus_flush(sd_bus *bus) {
ac3a84
                         return 0;
ac3a84
 
ac3a84
                 r = bus_poll(bus, false, UINT64_MAX);
ac3a84
-                if (r < 0)
ac3a84
+                if (r < 0) {
ac3a84
+                        if (ERRNO_IS_TRANSIENT(r))
ac3a84
+                                continue;
ac3a84
+
ac3a84
                         return r;
ac3a84
+                }
ac3a84
         }
ac3a84
 }
ac3a84