diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2015-05-27 08:16:14 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2015-05-27 08:16:14 -0400 |
commit | 8ab818626d8ef8cd303e0c16765252c6fb22ef17 (patch) | |
tree | 9eb8cba616d54dba65c439cacf23f5c5d5df4257 /src | |
parent | 233b58f3ac6d9ee34f0e428968c36b2e72ddb20c (diff) |
src/shared/util.h: import loop_write() from upstream
Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/shared/util.c | 38 | ||||
-rw-r--r-- | src/shared/util.h | 1 |
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); |