From 5b10b583581eac104805f67a87cf19f086447d86 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 2 May 2026 22:10:03 +0900 Subject: [PATCH] iovec-util: introduce iovec_done_and_memdup() It is similar to free_and_strdup(), but for struct iovec. --- src/basic/iovec-util.c | 15 +++++++++++++++ src/basic/iovec-util.h | 1 + src/test/test-iovec-util.c | 25 +++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/basic/iovec-util.c b/src/basic/iovec-util.c index dab734b901..429f08dea9 100644 --- a/src/basic/iovec-util.c +++ b/src/basic/iovec-util.c @@ -129,6 +129,21 @@ struct iovec* iovec_memdup(const struct iovec *source, struct iovec *ret) { return ret; } +int iovec_done_and_memdup(struct iovec *iovec, const struct iovec *source) { + assert(iovec); + + if (iovec_equal(iovec, source)) + return 0; + + struct iovec copy; + if (!iovec_memdup(source, ©)) + return -ENOMEM; + + iovec_done(iovec); + *iovec = copy; + return 1; +} + struct iovec* iovec_append(struct iovec *iovec, const struct iovec *append) { assert(iovec_is_valid(iovec)); diff --git a/src/basic/iovec-util.h b/src/basic/iovec-util.h index c8261861a0..a0a059550b 100644 --- a/src/basic/iovec-util.h +++ b/src/basic/iovec-util.h @@ -43,5 +43,6 @@ static inline bool iovec_equal(const struct iovec *a, const struct iovec *b) { } struct iovec* iovec_memdup(const struct iovec *source, struct iovec *ret); +int iovec_done_and_memdup(struct iovec *iovec, const struct iovec *source); struct iovec* iovec_append(struct iovec *iovec, const struct iovec *append); diff --git a/src/test/test-iovec-util.c b/src/test/test-iovec-util.c index bd73be1ea7..e510e86ca1 100644 --- a/src/test/test-iovec-util.c +++ b/src/test/test-iovec-util.c @@ -163,4 +163,29 @@ TEST(iovec_make_byte) { ASSERT_EQ(memcmp_nn(x.iov_base, x.iov_len, "x", 1), 0); } +TEST(iovec_done_and_memdup) { + _cleanup_(iovec_done) struct iovec iov = {}; + + ASSERT_OK_ZERO(iovec_done_and_memdup(&iov, NULL)); + ASSERT_TRUE(!iovec_is_set(&iov)); + ASSERT_OK_ZERO(iovec_done_and_memdup(&iov, &(struct iovec) {})); + ASSERT_TRUE(!iovec_is_set(&iov)); + ASSERT_OK_POSITIVE(iovec_done_and_memdup(&iov, &IOVEC_MAKE_STRING("aaa"))); + ASSERT_TRUE(iovec_equal(&iov, &IOVEC_MAKE_STRING("aaa"))); + ASSERT_OK_POSITIVE(iovec_done_and_memdup(&iov, &IOVEC_MAKE_STRING("bbbbb"))); + ASSERT_TRUE(iovec_equal(&iov, &IOVEC_MAKE_STRING("bbbbb"))); + ASSERT_OK_POSITIVE(iovec_done_and_memdup(&iov, NULL)); + ASSERT_TRUE(!iovec_is_set(&iov)); + ASSERT_OK_POSITIVE(iovec_done_and_memdup(&iov, &IOVEC_MAKE_STRING("ccc"))); + ASSERT_TRUE(iovec_equal(&iov, &IOVEC_MAKE_STRING("ccc"))); + ASSERT_OK_POSITIVE(iovec_done_and_memdup(&iov, &(struct iovec) {})); + ASSERT_TRUE(!iovec_is_set(&iov)); + ASSERT_OK_ZERO(iovec_done_and_memdup(&iov, &iov)); + ASSERT_TRUE(!iovec_is_set(&iov)); + ASSERT_OK_POSITIVE(iovec_done_and_memdup(&iov, &IOVEC_MAKE_STRING("ddd"))); + ASSERT_TRUE(iovec_equal(&iov, &IOVEC_MAKE_STRING("ddd"))); + ASSERT_OK_ZERO(iovec_done_and_memdup(&iov, &iov)); + ASSERT_TRUE(iovec_equal(&iov, &IOVEC_MAKE_STRING("ddd"))); +} + DEFINE_TEST_MAIN(LOG_INFO);