summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/util/util.c39
-rw-r--r--src/util/util.h5
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);