summaryrefslogtreecommitdiffstats
path: root/src/util/util.c
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2012-02-26 13:55:15 -0500
committerStephen Gallagher <sgallagh@redhat.com>2012-02-26 20:34:18 -0500
commit915b7f47219af0cedf5ddc146ab1598b3e6ae14a (patch)
treebf66d37538919b269e64cd0b514bf791de8c7ff5 /src/util/util.c
parent748ba184db97b7534254f97018fa04e8aa458fae (diff)
downloadsssd_unused-915b7f47219af0cedf5ddc146ab1598b3e6ae14a.tar.gz
sssd_unused-915b7f47219af0cedf5ddc146ab1598b3e6ae14a.tar.xz
sssd_unused-915b7f47219af0cedf5ddc146ab1598b3e6ae14a.zip
UTIL: Add function for atomic I/O
Diffstat (limited to 'src/util/util.c')
-rw-r--r--src/util/util.c39
1 files changed, 39 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;
+}