From f0f5c379cc5f5a39b4528fdd5936f9d5817e1496 Mon Sep 17 00:00:00 2001 From: Jan Cholasta Date: Sun, 26 Feb 2012 13:55:15 -0500 Subject: UTIL: Add function for atomic I/O --- src/util/util.c | 39 +++++++++++++++++++++++++++++++++++++++ src/util/util.h | 5 +++++ 2 files changed, 44 insertions(+) diff --git a/src/util/util.c b/src/util/util.c index ff55fdd7c..8e20ab714 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -20,6 +20,7 @@ #include #include +#include #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 */ +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 30413d9ce..7eb62a9b9 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); -- cgit