1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
16 #include "time-util.h"
18 int flush_fd(int fd) {
19 struct pollfd pollfd = {
25 /* Read from the specified file descriptor, until POLLIN is not set anymore, throwing away everything
26 * read. Note that some file descriptors (notable IP sockets) will trigger POLLIN even when no data can be read
27 * (due to IP packet checksum mismatches), hence this function is only safe to be non-blocking if the fd used
28 * was set to non-blocking too. */
35 r = poll(&pollfd, 1, 0);
45 l = read(fd, buf, sizeof(buf));
62 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
69 /* If called with nbytes == 0, let's call read() at least
70 * once, to validate the operation */
72 if (nbytes > (size_t) SSIZE_MAX)
78 k = read(fd, p, nbytes);
83 if (errno == EAGAIN && do_poll) {
85 /* We knowingly ignore any return value here,
86 * and expect that any error/EOF is reported
89 (void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
93 return n > 0 ? n : -errno;
99 assert((size_t) k <= nbytes);
104 } while (nbytes > 0);
109 int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
112 n = loop_read(fd, buf, nbytes, do_poll);
115 if ((size_t) n != nbytes)
121 int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
122 const uint8_t *p = buf;
127 if (_unlikely_(nbytes > (size_t) SSIZE_MAX))
133 k = write(fd, p, nbytes);
138 if (errno == EAGAIN && do_poll) {
139 /* We knowingly ignore any return value here,
140 * and expect that any error/EOF is reported
143 (void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
150 if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */
153 assert((size_t) k <= nbytes);
157 } while (nbytes > 0);
162 int pipe_eof(int fd) {
163 struct pollfd pollfd = {
165 .events = POLLIN|POLLHUP,
170 r = poll(&pollfd, 1, 0);
177 return pollfd.revents & POLLHUP;
180 int fd_wait_for_event(int fd, int event, usec_t t) {
182 struct pollfd pollfd = {
190 r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
196 return pollfd.revents;
199 static size_t nul_length(const uint8_t *p, size_t sz) {
214 ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
215 const uint8_t *q, *w, *e;
223 n = nul_length(q, e - q);
225 /* If there are more than the specified run length of
226 * NUL bytes, or if this is the beginning or the end
227 * of the buffer, then seek instead of write */
228 if ((n > run_length) ||
230 (n > 0 && q + n >= e)) {
232 l = write(fd, w, q - w);
239 if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
251 l = write(fd, w, q - w);
258 return q - (const uint8_t*) p;