diff options
author | Jan Cholasta <jcholast@redhat.com> | 2012-02-26 13:55:15 -0500 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2012-02-26 20:34:18 -0500 |
commit | 915b7f47219af0cedf5ddc146ab1598b3e6ae14a (patch) | |
tree | bf66d37538919b269e64cd0b514bf791de8c7ff5 /src/util/util.c | |
parent | 748ba184db97b7534254f97018fa04e8aa458fae (diff) | |
download | sssd-915b7f47219af0cedf5ddc146ab1598b3e6ae14a.tar.gz sssd-915b7f47219af0cedf5ddc146ab1598b3e6ae14a.tar.xz sssd-915b7f47219af0cedf5ddc146ab1598b3e6ae14a.zip |
UTIL: Add function for atomic I/O
Diffstat (limited to 'src/util/util.c')
-rw-r--r-- | src/util/util.c | 39 |
1 files changed, 39 insertions, 0 deletions
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 <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; +} |