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