]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-bus: handle -EINTR return from bus_poll()
authorLennart Poettering <lennart@poettering.net>
Mon, 21 Nov 2022 16:42:04 +0000 (17:42 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 22 Nov 2022 12:06:50 +0000 (13:06 +0100)
In sd_bus_wait(), let's convert EINTR to a return code of 0, thus asking
the caller do loop again and enter sd_bus_process() again (which will
not find any queued events). This way we'll not return an error on
something that isn't really an error. This should typically make sure
things are properly handled by the caller, magically, without eating up
the event entirely, and still giving the caller time to run some code if
they want.

src/libsystemd/sd-bus/bus-socket.c
src/libsystemd/sd-bus/sd-bus.c

index c94befef73fcd54f80c553b1202464ce7e78f3e9..253f41c636b5c4c8520659b792d57aaeb755a638 100644 (file)
@@ -1308,8 +1308,11 @@ int bus_socket_process_opening(sd_bus *b) {
         assert(b->state == BUS_OPENING);
 
         events = fd_wait_for_event(b->output_fd, POLLOUT, 0);
-        if (events < 0)
+        if (events < 0) {
+                if (ERRNO_IS_TRANSIENT(events))
+                        return 0;
                 return events;
+        }
         if (!(events & (POLLOUT|POLLERR|POLLHUP)))
                 return 0;
 
index ba5ef7de006f61740a1c375e8cd4c7081095501a..c75276f4bacc3c3abb5d43400b2dd5fc69a54a84 100644 (file)
@@ -2465,8 +2465,11 @@ _public_ int sd_bus_call(
                         left = UINT64_MAX;
 
                 r = bus_poll(bus, true, left);
-                if (r < 0)
+                if (r < 0) {
+                        if (ERRNO_IS_TRANSIENT(r))
+                                continue;
                         goto fail;
+                }
                 if (r == 0) {
                         r = -ETIMEDOUT;
                         goto fail;
@@ -3321,6 +3324,7 @@ static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
 }
 
 _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
+        int r;
 
         assert_return(bus, -EINVAL);
         assert_return(bus = bus_resolve(bus), -ENOPKG);
@@ -3335,7 +3339,11 @@ _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
         if (bus->rqueue_size > 0)
                 return 0;
 
-        return bus_poll(bus, false, timeout_usec);
+        r = bus_poll(bus, false, timeout_usec);
+        if (r < 0 && ERRNO_IS_TRANSIENT(r))
+                return 1; /* treat EINTR as success, but let's exit, so that the caller will call back into us soon. */
+
+        return r;
 }
 
 _public_ int sd_bus_flush(sd_bus *bus) {
@@ -3377,8 +3385,12 @@ _public_ int sd_bus_flush(sd_bus *bus) {
                         return 0;
 
                 r = bus_poll(bus, false, UINT64_MAX);
-                if (r < 0)
+                if (r < 0) {
+                        if (ERRNO_IS_TRANSIENT(r))
+                                continue;
+
                         return r;
+                }
         }
 }