summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/shared/util.c38
-rw-r--r--src/shared/util.h1
2 files changed, 39 insertions, 0 deletions
diff --git a/src/shared/util.c b/src/shared/util.c
index f726e0ee2b..88defdc4f2 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -906,6 +906,44 @@ int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
return 0;
}
+int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
+ const uint8_t *p = buf;
+
+ assert(fd >= 0);
+ assert(buf);
+
+ errno = 0;
+
+ do {
+ ssize_t k;
+
+ k = write(fd, p, nbytes);
+ if (k < 0) {
+ if (errno == EINTR)
+ continue;
+
+ if (errno == EAGAIN && do_poll) {
+ /* We knowingly ignore any return value here,
+ * and expect that any error/EOF is reported
+ * via write() */
+
+ fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
+ continue;
+ }
+
+ return -errno;
+ }
+
+ if (nbytes > 0 && k == 0) /* Can't really happen */
+ return -EIO;
+
+ p += k;
+ nbytes -= k;
+ } while (nbytes > 0);
+
+ return 0;
+}
+
char* dirname_malloc(const char *path) {
char *d, *dir, *dir2;
diff --git a/src/shared/util.h b/src/shared/util.h
index f6c8f75649..423210e2f0 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -221,6 +221,7 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
+int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
char* dirname_malloc(const char *path);