summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-06-10 11:43:40 +0200
committerDaan De Meyer <daan.j.demeyer@gmail.com>2020-06-10 20:06:10 +0200
commit0f2d351f790516bc3f1158d964c5f83f339addb2 (patch)
treef9df08ab66c5c7be26c92e1767d39835cc9f472c
parent24bd74ae03efc98272236bd0a98a1d7d090d540c (diff)
downloadsystemd-0f2d351f790516bc3f1158d964c5f83f339addb2.tar.gz
tree-wide: port to fd_wait_for_event()
Prompted by the discussion on #16110, let's migrate more code to fd_wait_for_event(). This only leaves 7 places where we call into poll()/poll() directly in our entire codebase. (one of which is fd_wait_for_event() itself)
-rw-r--r--src/basic/io-util.c29
-rw-r--r--src/basic/socket-util.c14
-rw-r--r--src/libsystemd/sd-bus/bus-socket.c20
-rw-r--r--src/libsystemd/sd-daemon/sd-daemon.c12
-rw-r--r--src/libsystemd/sd-netlink/sd-netlink.c16
-rw-r--r--src/libudev/libudev-monitor.c19
-rw-r--r--src/shared/utmp-wtmp.c15
-rw-r--r--src/shared/varlink.c36
-rw-r--r--src/sleep/sleep.c27
-rw-r--r--src/udev/udevadm-settle.c23
-rw-r--r--src/userdb/userwork.c15
11 files changed, 63 insertions, 163 deletions
diff --git a/src/basic/io-util.c b/src/basic/io-util.c
index 4b3d1c814f..18baadb1fe 100644
--- a/src/basic/io-util.c
+++ b/src/basic/io-util.c
@@ -11,10 +11,6 @@
#include "time-util.h"
int flush_fd(int fd) {
- struct pollfd pollfd = {
- .fd = fd,
- .events = POLLIN,
- };
int count = 0;
/* Read from the specified file descriptor, until POLLIN is not set anymore, throwing away everything
@@ -27,22 +23,18 @@ int flush_fd(int fd) {
ssize_t l;
int r;
- r = poll(&pollfd, 1, 0);
+ r = fd_wait_for_event(fd, POLLIN, 0);
if (r < 0) {
- if (errno == EINTR)
+ if (r == -EINTR)
continue;
- return -errno;
+ return r;
}
if (r == 0)
return count;
- if (pollfd.revents & POLLNVAL)
- return -EBADF;
-
l = read(fd, buf, sizeof(buf));
if (l < 0) {
-
if (errno == EINTR)
continue;
@@ -158,24 +150,15 @@ int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
}
int pipe_eof(int fd) {
- struct pollfd pollfd = {
- .fd = fd,
- .events = POLLIN|POLLHUP,
- };
-
int r;
- r = poll(&pollfd, 1, 0);
+ r = fd_wait_for_event(fd, POLLIN, 0);
if (r < 0)
- return -errno;
-
+ return r;
if (r == 0)
return 0;
- if (pollfd.revents & POLLNVAL)
- return -EBADF;
-
- return pollfd.revents & POLLHUP;
+ return !!(r & POLLHUP);
}
int fd_wait_for_event(int fd, int event, usec_t t) {
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index 2c990047fc..07f534f34d 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -21,6 +21,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
+#include "io-util.h"
#include "log.h"
#include "macro.h"
#include "memory-util.h"
@@ -968,10 +969,6 @@ fallback:
int flush_accept(int fd) {
- struct pollfd pollfd = {
- .fd = fd,
- .events = POLLIN,
- };
int r, b;
socklen_t l = sizeof(b);
@@ -992,19 +989,16 @@ int flush_accept(int fd) {
for (unsigned iteration = 0;; iteration++) {
int cfd;
- r = poll(&pollfd, 1, 0);
+ r = fd_wait_for_event(fd, POLLIN, 0);
if (r < 0) {
- if (errno == EINTR)
+ if (r == -EINTR)
continue;
- return -errno;
+ return r;
}
if (r == 0)
return 0;
- if (pollfd.revents & POLLNVAL)
- return -EBADF;
-
if (iteration >= MAX_FLUSH_ITERATIONS)
return log_debug_errno(SYNTHETIC_ERRNO(EBUSY),
"Failed to flush connections within " STRINGIFY(MAX_FLUSH_ITERATIONS) " iterations.");
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
index 778f80377f..fc7e8e844a 100644
--- a/src/libsystemd/sd-bus/bus-socket.c
+++ b/src/libsystemd/sd-bus/bus-socket.c
@@ -1262,23 +1262,15 @@ int bus_socket_read_message(sd_bus *bus) {
}
int bus_socket_process_opening(sd_bus *b) {
- int error = 0;
+ int error = 0, events, r;
socklen_t slen = sizeof(error);
- struct pollfd p = {
- .fd = b->output_fd,
- .events = POLLOUT,
- };
- int r;
assert(b->state == BUS_OPENING);
- r = poll(&p, 1, 0);
- if (r < 0)
- return -errno;
- if (p.revents & POLLNVAL)
- return -EBADF;
-
- if (!(p.revents & (POLLOUT|POLLERR|POLLHUP)))
+ events = fd_wait_for_event(b->output_fd, POLLOUT, 0);
+ if (events < 0)
+ return events;
+ if (!(events & (POLLOUT|POLLERR|POLLHUP)))
return 0;
r = getsockopt(b->output_fd, SOL_SOCKET, SO_ERROR, &error, &slen);
@@ -1286,7 +1278,7 @@ int bus_socket_process_opening(sd_bus *b) {
b->last_connect_error = errno;
else if (error != 0)
b->last_connect_error = error;
- else if (p.revents & (POLLERR|POLLHUP))
+ else if (events & (POLLERR|POLLHUP))
b->last_connect_error = ECONNREFUSED;
else
return bus_socket_start_auth(b);
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
index 0bc0fc16ae..bbe7cd76d5 100644
--- a/src/libsystemd/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
@@ -555,7 +555,6 @@ finish:
_public_ int sd_notify_barrier(int unset_environment, uint64_t timeout) {
_cleanup_close_pair_ int pipe_fd[2] = { -1, -1 };
- struct timespec ts;
int r;
if (pipe2(pipe_fd, O_CLOEXEC) < 0)
@@ -567,18 +566,11 @@ _public_ int sd_notify_barrier(int unset_environment, uint64_t timeout) {
pipe_fd[1] = safe_close(pipe_fd[1]);
- struct pollfd pfd = {
- .fd = pipe_fd[0],
- /* POLLHUP is implicit */
- .events = 0,
- };
- r = ppoll(&pfd, 1, timeout == UINT64_MAX ? NULL : timespec_store(&ts, timeout), NULL);
+ r = fd_wait_for_event(pipe_fd[0], 0 /* POLLHUP is implicit */, timeout);
if (r < 0)
- return -errno;
+ return r;
if (r == 0)
return -ETIMEDOUT;
- if (pfd.revents & POLLNVAL)
- return -EBADF;
return 1;
}
diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c
index ddeb4a7992..91670ee324 100644
--- a/src/libsystemd/sd-netlink/sd-netlink.c
+++ b/src/libsystemd/sd-netlink/sd-netlink.c
@@ -7,6 +7,7 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "hashmap.h"
+#include "io-util.h"
#include "macro.h"
#include "netlink-internal.h"
#include "netlink-slot.h"
@@ -462,7 +463,6 @@ static usec_t calc_elapse(uint64_t usec) {
}
static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) {
- struct timespec ts;
usec_t m = USEC_INFINITY;
int r, e;
@@ -491,23 +491,15 @@ static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) {
}
}
- if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m))
+ if (timeout_usec != (uint64_t) -1 && (m == USEC_INFINITY || timeout_usec < m))
m = timeout_usec;
- struct pollfd p = {
- .fd = rtnl->fd,
- .events = e,
- };
-
- r = ppoll(&p, 1, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL);
+ r = fd_wait_for_event(rtnl->fd, e, m);
if (r < 0)
- return -errno;
+ return r;
if (r == 0)
return 0;
- if (p.revents & POLLNVAL)
- return -EBADF;
-
return 1;
}
diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c
index bf23021b53..5bec7418b8 100644
--- a/src/libudev/libudev-monitor.c
+++ b/src/libudev/libudev-monitor.c
@@ -9,6 +9,7 @@
#include "device-monitor-private.h"
#include "device-private.h"
#include "device-util.h"
+#include "io-util.h"
#include "libudev-device-internal.h"
#include "string-util.h"
@@ -191,17 +192,11 @@ _public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor) {
}
static int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_device **ret) {
- struct pollfd pfd;
int r;
assert(udev_monitor);
assert(ret);
- pfd = (struct pollfd) {
- .fd = device_monitor_get_fd(udev_monitor->monitor),
- .events = POLLIN,
- };
-
for (;;) {
/* r == 0 means a device is received but it does not pass the current filter. */
r = device_monitor_receive_device(udev_monitor->monitor, ret);
@@ -209,20 +204,18 @@ static int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_
return r;
for (;;) {
- /* wait next message */
- r = poll(&pfd, 1, 0);
+ /* Wait for next message */
+ r = fd_wait_for_event(device_monitor_get_fd(udev_monitor->monitor), POLLIN, 0);
if (r < 0) {
- if (IN_SET(errno, EINTR, EAGAIN))
+ if (IN_SET(r, -EINTR, -EAGAIN))
continue;
- return -errno;
+ return r;
}
if (r == 0)
return -EAGAIN;
- if (pfd.revents & POLLNVAL)
- return -EBADF;
- /* receive next message */
+ /* Receive next message */
break;
}
}
diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c
index 7d0d90247c..9debb54390 100644
--- a/src/shared/utmp-wtmp.c
+++ b/src/shared/utmp-wtmp.c
@@ -14,6 +14,7 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "hostname-util.h"
+#include "io-util.h"
#include "macro.h"
#include "memory-util.h"
#include "path-util.h"
@@ -297,7 +298,7 @@ int utmp_put_runlevel(int runlevel, int previous) {
return write_entry_both(&store);
}
-#define TIMEOUT_MSEC 50
+#define TIMEOUT_USEC (50 * USEC_PER_MSEC)
static int write_to_terminal(const char *tty, const char *message) {
_cleanup_close_ int fd = -1;
@@ -315,14 +316,10 @@ static int write_to_terminal(const char *tty, const char *message) {
p = message;
left = strlen(message);
- end = now(CLOCK_MONOTONIC) + TIMEOUT_MSEC*USEC_PER_MSEC;
+ end = now(CLOCK_MONOTONIC) + TIMEOUT_USEC;
while (left > 0) {
ssize_t n;
- struct pollfd pollfd = {
- .fd = fd,
- .events = POLLOUT,
- };
usec_t t;
int k;
@@ -331,13 +328,11 @@ static int write_to_terminal(const char *tty, const char *message) {
if (t >= end)
return -ETIME;
- k = poll(&pollfd, 1, (end - t) / USEC_PER_MSEC);
+ k = fd_wait_for_event(fd, POLLOUT, end - t);
if (k < 0)
- return -errno;
+ return k;
if (k == 0)
return -ETIME;
- if (pollfd.revents & POLLNVAL)
- return -EBADF;
n = write(fd, p, left);
if (n < 0) {
diff --git a/src/shared/varlink.c b/src/shared/varlink.c
index c0b5874225..1f4d5a614c 100644
--- a/src/shared/varlink.c
+++ b/src/shared/varlink.c
@@ -6,6 +6,7 @@
#include "errno-util.h"
#include "fd-util.h"
#include "hashmap.h"
+#include "io-util.h"
#include "list.h"
#include "process-util.h"
#include "set.h"
@@ -1003,8 +1004,6 @@ static void handle_revents(Varlink *v, int revents) {
}
int varlink_wait(Varlink *v, usec_t timeout) {
- struct timespec ts;
- struct pollfd pfd;
int r, fd, events;
usec_t t;
@@ -1038,23 +1037,13 @@ int varlink_wait(Varlink *v, usec_t timeout) {
if (events < 0)
return events;
- pfd = (struct pollfd) {
- .fd = fd,
- .events = events,
- };
-
- r = ppoll(&pfd, 1,
- t == USEC_INFINITY ? NULL : timespec_store(&ts, t),
- NULL);
+ r = fd_wait_for_event(fd, events, t);
if (r < 0)
- return -errno;
+ return r;
if (r == 0)
return 0;
- if (pfd.revents & POLLNVAL)
- return -EBADF;
-
- handle_revents(v, pfd.revents);
+ handle_revents(v, r);
return 1;
}
@@ -1123,8 +1112,6 @@ int varlink_flush(Varlink *v) {
return -ENOTCONN;
for (;;) {
- struct pollfd pfd;
-
if (v->output_buffer_size == 0)
break;
if (v->write_disconnected)
@@ -1138,20 +1125,13 @@ int varlink_flush(Varlink *v) {
continue;
}
- pfd = (struct pollfd) {
- .fd = v->fd,
- .events = POLLOUT,
- };
-
- r = poll(&pfd, 1, -1);
+ r = fd_wait_for_event(v->fd, POLLOUT, USEC_INFINITY);
if (r < 0)
- return -errno;
+ return r;
- assert(r > 0);
- if (pfd.revents & POLLNVAL)
- return -EBADF;
+ assert(r != 0);
- handle_revents(v, pfd.revents);
+ handle_revents(v, r);
}
return ret;
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
index 4f9c23099a..11c51fb32b 100644
--- a/src/sleep/sleep.c
+++ b/src/sleep/sleep.c
@@ -23,6 +23,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
+#include "io-util.h"
#include "log.h"
#include "main-func.h"
#include "parse-util.h"
@@ -239,7 +240,6 @@ static int execute_s2h(const SleepConfig *sleep_config) {
_cleanup_close_ int tfd = -1;
char buf[FORMAT_TIMESPAN_MAX];
struct itimerspec ts = {};
- struct pollfd fds;
int r;
assert(sleep_config);
@@ -261,34 +261,25 @@ static int execute_s2h(const SleepConfig *sleep_config) {
if (r < 0)
return r;
- fds = (struct pollfd) {
- .fd = tfd,
- .events = POLLIN,
- };
- r = poll(&fds, 1, 0);
+ r = fd_wait_for_event(tfd, POLLIN, 0);
if (r < 0)
- return log_error_errno(errno, "Error polling timerfd: %m");
+ return log_error_errno(r, "Error polling timerfd: %m");
+ if (!FLAGS_SET(r, POLLIN)) /* We woke up before the alarm time, we are done. */
+ return 0;
tfd = safe_close(tfd);
- if (FLAGS_SET(fds.revents, POLLNVAL))
- return log_error_errno(SYNTHETIC_ERRNO(EBADF), "Invalid timer fd to sleep on?");
-
- if (!FLAGS_SET(fds.revents, POLLIN)) /* We woke up before the alarm time, we are done. */
- return 0;
-
/* If woken up after alarm time, hibernate */
log_debug("Attempting to hibernate after waking from %s timer",
format_timespan(buf, sizeof(buf), sleep_config->hibernate_delay_sec, USEC_PER_SEC));
r = execute(sleep_config->hibernate_modes, sleep_config->hibernate_states);
if (r < 0) {
- log_notice("Couldn't hibernate, will try to suspend again.");
+ log_notice_errno(r, "Couldn't hibernate, will try to suspend again.");
+
r = execute(sleep_config->suspend_modes, sleep_config->suspend_states);
- if (r < 0) {
- log_notice("Could neither hibernate nor suspend again, giving up.");
- return r;
- }
+ if (r < 0)
+ return log_notice_errno(r, "Could neither hibernate nor suspend again, giving up.");
}
return 0;
diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c
index 1fa267c831..5730349ba5 100644
--- a/src/udev/udevadm-settle.c
+++ b/src/udev/udevadm-settle.c
@@ -15,6 +15,7 @@
#include "sd-bus.h"
#include "sd-login.h"
+#include "io-util.h"
#include "libudev-util.h"
#include "string-util.h"
#include "strv.h"
@@ -141,9 +142,8 @@ static int emit_deprecation_warning(void) {
int settle_main(int argc, char *argv[], void *userdata) {
_cleanup_(udev_queue_unrefp) struct udev_queue *queue = NULL;
- struct pollfd pfd;
usec_t deadline;
- int r;
+ int r, fd;
r = parse_argv(argc, argv);
if (r <= 0)
@@ -177,17 +177,12 @@ int settle_main(int argc, char *argv[], void *userdata) {
if (!queue)
return log_error_errno(errno, "Failed to get udev queue: %m");
- r = udev_queue_get_fd(queue);
- if (r < 0) {
- log_debug_errno(r, "Queue is empty, nothing to watch.");
+ fd = udev_queue_get_fd(queue);
+ if (fd < 0) {
+ log_debug_errno(fd, "Queue is empty, nothing to watch: %m");
return 0;
}
- pfd = (struct pollfd) {
- .events = POLLIN,
- .fd = r,
- };
-
(void) emit_deprecation_warning();
for (;;) {
@@ -202,12 +197,10 @@ int settle_main(int argc, char *argv[], void *userdata) {
return -ETIMEDOUT;
/* wake up when queue becomes empty */
- r = poll(&pfd, 1, MSEC_PER_SEC);
+ r = fd_wait_for_event(fd, POLLIN, MSEC_PER_SEC);
if (r < 0)
- return -errno;
- if (pfd.revents & POLLNVAL)
- return -EBADF;
- if (r > 0 && pfd.revents & POLLIN) {
+ return r;
+ if (r & POLLIN) {
r = udev_queue_flush(queue);
if (r < 0)
return log_error_errno(r, "Failed to flush queue: %m");
diff --git a/src/userdb/userwork.c b/src/userdb/userwork.c
index 4a8c98384d..732063f6c7 100644
--- a/src/userdb/userwork.c
+++ b/src/userdb/userwork.c
@@ -9,6 +9,7 @@
#include "fd-util.h"
#include "group-record-nss.h"
#include "group-record.h"
+#include "io-util.h"
#include "main-func.h"
#include "process-util.h"
#include "strv.h"
@@ -747,20 +748,14 @@ static int run(int argc, char *argv[]) {
return log_error_errno(fd, "Failed to accept() from listening socket: %m");
if (now(CLOCK_MONOTONIC) <= usec_add(n, PRESSURE_SLEEP_TIME_USEC)) {
- struct pollfd pfd = {
- .fd = listen_fd,
- .events = POLLIN,
- };
-
/* We only slept a very short time? If so, let's see if there are more sockets
* pending, and if so, let's ask our parent for more workers */
- if (poll(&pfd, 1, 0) < 0)
- return log_error_errno(errno, "Failed to test for POLLIN on listening socket: %m");
- if (FLAGS_SET(pfd.revents, POLLNVAL))
- return log_error_errno(SYNTHETIC_ERRNO(EBADF), "Listening socket dead?");
+ r = fd_wait_for_event(listen_fd, POLLIN, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to test for POLLIN on listening socket: %m");
- if (FLAGS_SET(pfd.revents, POLLIN)) {
+ if (FLAGS_SET(r, POLLIN)) {
pid_t parent;
parent = getppid();