summaryrefslogtreecommitdiffstats
path: root/source3/lib
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2014-12-27 13:16:20 +0000
committerJeremy Allison <jra@samba.org>2014-12-30 00:25:08 +0100
commit8855c0332a5ad2996873727074af6974f1238d5f (patch)
tree976c31cba5a48a051bd773d6ab79ba60772e6f4a /source3/lib
parentb4ceef0230a13a66e91f33d831a5e77babaef0ed (diff)
downloadsamba-8855c0332a5ad2996873727074af6974f1238d5f.tar.gz
samba-8855c0332a5ad2996873727074af6974f1238d5f.tar.xz
samba-8855c0332a5ad2996873727074af6974f1238d5f.zip
lib: Add iov_advance
This chops off n bytes from an iovec array. Used for short writev's Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/iov_buf.c33
-rw-r--r--source3/lib/iov_buf.h2
2 files changed, 35 insertions, 0 deletions
diff --git a/source3/lib/iov_buf.c b/source3/lib/iov_buf.c
index e05dfc9524..f0e05a64da 100644
--- a/source3/lib/iov_buf.c
+++ b/source3/lib/iov_buf.c
@@ -53,3 +53,36 @@ ssize_t iov_buf(const struct iovec *iov, int iovcnt,
return needed;
}
+
+bool iov_advance(struct iovec **iov, int *iovcnt, size_t n)
+{
+ struct iovec *v = *iov;
+ int cnt = *iovcnt;
+
+ while (n > 0) {
+ if (cnt == 0) {
+ return false;
+ }
+ if (n < v->iov_len) {
+ v->iov_base = (char *)v->iov_base + n;
+ v->iov_len -= n;
+ break;
+ }
+ n -= v->iov_len;
+ v += 1;
+ cnt -= 1;
+ }
+
+ /*
+ * Skip 0-length iovec's
+ */
+
+ while ((cnt > 0) && (v->iov_len == 0)) {
+ v += 1;
+ cnt -= 1;
+ }
+
+ *iov = v;
+ *iovcnt = cnt;
+ return true;
+}
diff --git a/source3/lib/iov_buf.h b/source3/lib/iov_buf.h
index 397e906eb4..8f0ca266da 100644
--- a/source3/lib/iov_buf.h
+++ b/source3/lib/iov_buf.h
@@ -22,9 +22,11 @@
#include <unistd.h>
#include <stdint.h>
+#include <stdbool.h>
ssize_t iov_buflen(const struct iovec *iov, int iovlen);
ssize_t iov_buf(const struct iovec *iov, int iovcnt,
uint8_t *buf, size_t buflen);
+bool iov_advance(struct iovec **iov, int *iovcnt, size_t n);
#endif