diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/util/util.c | 39 | ||||
-rw-r--r-- | src/util/util.h | 5 |
2 files changed, 44 insertions, 0 deletions
diff --git a/src/util/util.c b/src/util/util.c index ff55fdd7..8e20ab71 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -20,6 +20,7 @@ #include <ctype.h> #include <netdb.h> +#include <poll.h> #include "talloc.h" #include "util/util.h" @@ -609,3 +610,41 @@ void to_sized_string(struct sized_string *out, const char *in) out->len = 0; } } + +/* based on code from libssh <http://www.libssh.org> */ +ssize_t sss_atomic_io(int fd, void *buf, size_t n, bool do_read) +{ + char *b = buf; + size_t pos = 0; + ssize_t res; + struct pollfd pfd; + + pfd.fd = fd; + pfd.events = do_read ? POLLIN : POLLOUT; + + while (n > pos) { + if (do_read) { + res = read(fd, b + pos, n - pos); + } else { + res = write(fd, b + pos, n - pos); + } + switch (res) { + case -1: + if (errno == EINTR) { + continue; + } + if (errno == EAGAIN || errno == EWOULDBLOCK) { + (void) poll(&pfd, 1, -1); + continue; + } + return -1; + case 0: + errno = EPIPE; + return pos; + default: + pos += (size_t) res; + } + } + + return pos; +} diff --git a/src/util/util.h b/src/util/util.h index 30413d9c..7eb62a9b 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -506,6 +506,11 @@ errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx, char * sss_escape_ip_address(TALLOC_CTX *mem_ctx, int family, const char *addr); +ssize_t sss_atomic_io(int fd, void *buf, size_t n, bool do_read); + +#define sss_atomic_read(fd, buf, n) sss_atomic_io(fd, buf, n, true) +#define sss_atomic_write(fd, buf, n) sss_atomic_io(fd, buf, n, false) + /* from sss_tc_utf8.c */ char * sss_tc_utf8_str_tolower(TALLOC_CTX *mem_ctx, const char *s); |