return sum;
}
-bool iovec_increment(struct iovec *iovec, size_t n, size_t k) {
+bool iovec_inc_many(struct iovec *iovec, size_t n, size_t k) {
assert(iovec || n == 0);
/* Returns true if there is nothing else to send (bytes written cover all of the iovec),
* false if there's still work to do. */
+ bool have = false;
FOREACH_ARRAY(j, iovec, n) {
- size_t sub;
-
if (j->iov_len == 0)
continue;
if (k == 0)
return false;
- sub = MIN(j->iov_len, k);
- j->iov_len -= sub;
- j->iov_base = (uint8_t*) j->iov_base + sub;
+ size_t sub = MIN(j->iov_len, k);
+ iovec_inc(j, sub);
k -= sub;
+
+ have = have || iovec_is_set(j);
}
assert(k == 0); /* Anything else would mean that we wrote more bytes than available,
* or the kernel reported writing more bytes than sent. */
- return true;
+
+ return !have;
}
struct iovec* iovec_make_string(struct iovec *iovec, const char *s) {
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "iovec-util.h"
+#include "iovec-wrapper.h"
#include "memory-util.h"
#include "tests.h"
ASSERT_FALSE(iovec_is_set(iovec_inc(&empty, 1)));
}
+TEST(iovec_inc_many) {
+ ASSERT_TRUE(iovec_inc_many(NULL, 0, 0));
+ ASSERT_TRUE(iovec_inc_many(&(struct iovec) {}, 0, 0));
+ ASSERT_TRUE(iovec_inc_many(&(struct iovec) {}, 1, 0));
+
+ _cleanup_(iovw_done) struct iovec_wrapper iovw = {};
+ ASSERT_OK(iovw_put_iov(&iovw, &IOVEC_MAKE_STRING("aaa")));
+ ASSERT_OK(iovw_put_iov(&iovw, &IOVEC_MAKE_STRING("bbb")));
+ ASSERT_OK(iovw_put_iov(&iovw, &IOVEC_MAKE_STRING("ccc")));
+
+ ASSERT_FALSE(iovec_inc_many(iovw.iovec, iovw.count, 0));
+ ASSERT_TRUE(iovec_equal(&iovw.iovec[0], &IOVEC_MAKE_STRING("aaa")));
+ ASSERT_TRUE(iovec_equal(&iovw.iovec[1], &IOVEC_MAKE_STRING("bbb")));
+ ASSERT_TRUE(iovec_equal(&iovw.iovec[2], &IOVEC_MAKE_STRING("ccc")));
+
+ ASSERT_FALSE(iovec_inc_many(iovw.iovec, iovw.count, 1));
+ ASSERT_TRUE(iovec_equal(&iovw.iovec[0], &IOVEC_MAKE_STRING("aa")));
+ ASSERT_TRUE(iovec_equal(&iovw.iovec[1], &IOVEC_MAKE_STRING("bbb")));
+ ASSERT_TRUE(iovec_equal(&iovw.iovec[2], &IOVEC_MAKE_STRING("ccc")));
+
+ ASSERT_FALSE(iovec_inc_many(iovw.iovec, iovw.count, 3));
+ ASSERT_FALSE(iovec_is_set(&iovw.iovec[0]));
+ ASSERT_NULL(iovw.iovec[0].iov_base);
+ ASSERT_EQ(iovw.iovec[0].iov_len, 0u);
+ ASSERT_TRUE(iovec_equal(&iovw.iovec[1], &IOVEC_MAKE_STRING("bb")));
+ ASSERT_TRUE(iovec_equal(&iovw.iovec[2], &IOVEC_MAKE_STRING("ccc")));
+
+ ASSERT_FALSE(iovec_inc_many(iovw.iovec, iovw.count, 4));
+ ASSERT_NULL(iovw.iovec[0].iov_base);
+ ASSERT_EQ(iovw.iovec[0].iov_len, 0u);
+ ASSERT_NULL(iovw.iovec[1].iov_base);
+ ASSERT_EQ(iovw.iovec[1].iov_len, 0u);
+ ASSERT_TRUE(iovec_equal(&iovw.iovec[2], &IOVEC_MAKE_STRING("c")));
+
+ ASSERT_TRUE(iovec_inc_many(iovw.iovec, iovw.count, 1));
+ ASSERT_NULL(iovw.iovec[0].iov_base);
+ ASSERT_EQ(iovw.iovec[0].iov_len, 0u);
+ ASSERT_NULL(iovw.iovec[1].iov_base);
+ ASSERT_EQ(iovw.iovec[1].iov_len, 0u);
+ ASSERT_NULL(iovw.iovec[2].iov_base);
+ ASSERT_EQ(iovw.iovec[2].iov_len, 0u);
+
+ ASSERT_TRUE(iovec_inc_many(iovw.iovec, iovw.count, 0));
+ ASSERT_NULL(iovw.iovec[0].iov_base);
+ ASSERT_EQ(iovw.iovec[0].iov_len, 0u);
+ ASSERT_NULL(iovw.iovec[1].iov_base);
+ ASSERT_EQ(iovw.iovec[1].iov_len, 0u);
+ ASSERT_NULL(iovw.iovec[2].iov_base);
+ ASSERT_EQ(iovw.iovec[2].iov_len, 0u);
+
+ ASSERT_SIGNAL(iovec_inc_many(iovw.iovec, iovw.count, 1), SIGABRT);
+}
+
TEST(iovec_memcmp) {
struct iovec iov1 = CONST_IOVEC_MAKE_STRING("abcdef"), iov2 = IOVEC_MAKE_STRING("bcdefg"), empty = {};