]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
iovec-util: introduce iovec_done_and_memdup()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 2 May 2026 13:10:03 +0000 (22:10 +0900)
committerLuca Boccassi <luca.boccassi@gmail.com>
Sun, 3 May 2026 09:18:38 +0000 (10:18 +0100)
It is similar to free_and_strdup(), but for struct iovec.

src/basic/iovec-util.c
src/basic/iovec-util.h
src/test/test-iovec-util.c

index dab734b9010f176c72c6157b522a24c99357e6c7..429f08dea9ad44a9f0bda6bf0490f0ddc1afa1a3 100644 (file)
@@ -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, &copy))
+                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));
 
index c8261861a0ff787bd25d23ade417c17eee261ebe..a0a059550b7dbb2a5b3af176c36db6eb73359765 100644 (file)
@@ -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);
index bd73be1ea76e67fa66a67d3f3559855ea7cdc56e..e510e86ca144aedb22eaeb4f5ccd6627c181978b 100644 (file)
@@ -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);