Let's split these APIs out, they are kinda their own thing.
return q - (const uint8_t*) p;
}
-
-struct iovec_wrapper *iovw_new(void) {
- return malloc0(sizeof(struct iovec_wrapper));
-}
-
-void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors) {
- if (free_vectors)
- for (size_t i = 0; i < iovw->count; i++)
- free(iovw->iovec[i].iov_base);
-
- iovw->iovec = mfree(iovw->iovec);
- iovw->count = 0;
-}
-
-struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw) {
- iovw_free_contents(iovw, true);
-
- return mfree(iovw);
-}
-
-struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw) {
- iovw_free_contents(iovw, false);
-
- return mfree(iovw);
-}
-
-int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len) {
- if (iovw->count >= IOV_MAX)
- return -E2BIG;
-
- if (!GREEDY_REALLOC(iovw->iovec, iovw->count + 1))
- return -ENOMEM;
-
- iovw->iovec[iovw->count++] = IOVEC_MAKE(data, len);
- return 0;
-}
-
-int iovw_put_string_field(struct iovec_wrapper *iovw, const char *field, const char *value) {
- _cleanup_free_ char *x = NULL;
- int r;
-
- x = strjoin(field, value);
- if (!x)
- return -ENOMEM;
-
- r = iovw_put(iovw, x, strlen(x));
- if (r >= 0)
- TAKE_PTR(x);
-
- return r;
-}
-
-int iovw_put_string_field_free(struct iovec_wrapper *iovw, const char *field, char *value) {
- _cleanup_free_ _unused_ char *free_ptr = value;
-
- return iovw_put_string_field(iovw, field, value);
-}
-
-void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new) {
- for (size_t i = 0; i < iovw->count; i++)
- iovw->iovec[i].iov_base = (char *)iovw->iovec[i].iov_base - old + new;
-}
-
-size_t iovw_size(struct iovec_wrapper *iovw) {
- size_t n = 0;
-
- for (size_t i = 0; i < iovw->count; i++)
- n += iovw->iovec[i].iov_len;
-
- return n;
-}
-
-int iovw_append(struct iovec_wrapper *target, const struct iovec_wrapper *source) {
- size_t original_count;
- int r;
-
- assert(target);
-
- /* This duplicates the source and merges it into the target. */
-
- if (iovw_isempty(source))
- return 0;
-
- original_count = target->count;
-
- FOREACH_ARRAY(iovec, source->iovec, source->count) {
- void *dup;
-
- dup = memdup(iovec->iov_base, iovec->iov_len);
- if (!dup) {
- r = -ENOMEM;
- goto rollback;
- }
-
- r = iovw_consume(target, dup, iovec->iov_len);
- if (r < 0)
- goto rollback;
- }
-
- return 0;
-
-rollback:
- for (size_t i = original_count; i < target->count; i++)
- free(target->iovec[i].iov_base);
-
- target->count = original_count;
- return r;
-}
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
-#include <sys/uio.h>
#include "macro.h"
#include "time-util.h"
return FILE_SIZE_VALID(l);
}
-
-struct iovec_wrapper {
- struct iovec *iovec;
- size_t count;
-};
-
-struct iovec_wrapper *iovw_new(void);
-struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw);
-struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct iovec_wrapper*, iovw_free_free);
-
-void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors);
-
-int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len);
-static inline int iovw_consume(struct iovec_wrapper *iovw, void *data, size_t len) {
- /* Move data into iovw or free on error */
- int r;
-
- r = iovw_put(iovw, data, len);
- if (r < 0)
- free(data);
-
- return r;
-}
-
-static inline bool iovw_isempty(const struct iovec_wrapper *iovw) {
- return !iovw || iovw->count == 0;
-}
-
-int iovw_put_string_field(struct iovec_wrapper *iovw, const char *field, const char *value);
-int iovw_put_string_field_free(struct iovec_wrapper *iovw, const char *field, char *value);
-void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new);
-size_t iovw_size(struct iovec_wrapper *iovw);
-int iovw_append(struct iovec_wrapper *target, const struct iovec_wrapper *source);
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "alloc-util.h"
+#include "iovec-util.h"
+#include "iovec-wrapper.h"
+#include "string-util.h"
+
+struct iovec_wrapper *iovw_new(void) {
+ return new0(struct iovec_wrapper, 1);
+}
+
+void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors) {
+ assert(iovw);
+
+ if (free_vectors)
+ for (size_t i = 0; i < iovw->count; i++)
+ free(iovw->iovec[i].iov_base);
+
+ iovw->iovec = mfree(iovw->iovec);
+ iovw->count = 0;
+}
+
+struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw) {
+ if (!iovw)
+ return NULL;
+
+ iovw_free_contents(iovw, /* free_vectors= */ true);
+ return mfree(iovw);
+}
+
+struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw) {
+ if (!iovw)
+ return NULL;
+
+ iovw_free_contents(iovw, /* free_vectors= */ false);
+ return mfree(iovw);
+}
+
+int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len) {
+ assert(iovw);
+
+ if (len == 0)
+ return 0;
+
+ assert(data);
+
+ if (iovw->count >= IOV_MAX)
+ return -E2BIG;
+
+ if (!GREEDY_REALLOC(iovw->iovec, iovw->count + 1))
+ return -ENOMEM;
+
+ iovw->iovec[iovw->count++] = IOVEC_MAKE(data, len);
+ return 0;
+}
+
+int iovw_put_string_field(struct iovec_wrapper *iovw, const char *field, const char *value) {
+ _cleanup_free_ char *x = NULL;
+ int r;
+
+ assert(iovw);
+
+ x = strjoin(field, value);
+ if (!x)
+ return -ENOMEM;
+
+ r = iovw_put(iovw, x, strlen(x));
+ if (r >= 0)
+ TAKE_PTR(x);
+
+ return r;
+}
+
+int iovw_put_string_field_free(struct iovec_wrapper *iovw, const char *field, char *value) {
+ _cleanup_free_ _unused_ char *free_ptr = value;
+
+ return iovw_put_string_field(iovw, field, value);
+}
+
+void iovw_rebase(struct iovec_wrapper *iovw, void *old, void *new) {
+ assert(iovw);
+
+ FOREACH_ARRAY(i, iovw->iovec, iovw->count) {
+ assert(i->iov_base >= old);
+ i->iov_base = (uint8_t*) i->iov_base - (uint8_t*) old + (uint8_t*) new;
+ }
+}
+
+size_t iovw_size(const struct iovec_wrapper *iovw) {
+ if (!iovw)
+ return 0;
+
+ return iovec_total_size(iovw->iovec, iovw->count);
+}
+
+int iovw_append(struct iovec_wrapper *target, const struct iovec_wrapper *source) {
+ size_t original_count;
+ int r;
+
+ assert(target);
+
+ /* This duplicates the source and merges it into the target. */
+
+ if (iovw_isempty(source))
+ return 0;
+
+ original_count = target->count;
+
+ FOREACH_ARRAY(iovec, source->iovec, source->count) {
+ void *dup;
+
+ dup = memdup(iovec->iov_base, iovec->iov_len);
+ if (!dup) {
+ r = -ENOMEM;
+ goto rollback;
+ }
+
+ r = iovw_consume(target, dup, iovec->iov_len);
+ if (r < 0)
+ goto rollback;
+ }
+
+ return 0;
+
+rollback:
+ for (size_t i = original_count; i < target->count; i++)
+ free(target->iovec[i].iov_base);
+
+ target->count = original_count;
+ return r;
+}
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#include "macro.h"
+
+struct iovec_wrapper {
+ struct iovec *iovec;
+ size_t count;
+};
+
+struct iovec_wrapper *iovw_new(void);
+struct iovec_wrapper *iovw_free(struct iovec_wrapper *iovw);
+struct iovec_wrapper *iovw_free_free(struct iovec_wrapper *iovw);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct iovec_wrapper*, iovw_free_free);
+
+void iovw_free_contents(struct iovec_wrapper *iovw, bool free_vectors);
+
+int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len);
+static inline int iovw_consume(struct iovec_wrapper *iovw, void *data, size_t len) {
+ /* Move data into iovw or free on error */
+ int r;
+
+ r = iovw_put(iovw, data, len);
+ if (r < 0)
+ free(data);
+
+ return r;
+}
+
+static inline bool iovw_isempty(const struct iovec_wrapper *iovw) {
+ return !iovw || iovw->count == 0;
+}
+
+int iovw_put_string_field(struct iovec_wrapper *iovw, const char *field, const char *value);
+int iovw_put_string_field_free(struct iovec_wrapper *iovw, const char *field, char *value);
+void iovw_rebase(struct iovec_wrapper *iovw, void *old, void *new);
+size_t iovw_size(const struct iovec_wrapper *iovw);
+int iovw_append(struct iovec_wrapper *target, const struct iovec_wrapper *source);
'initrd-util.c',
'inotify-util.c',
'io-util.c',
- 'iovec-util.c',
'ioprio-util.c',
+ 'iovec-util.c',
+ 'iovec-wrapper.c',
'label.c',
'limits-util.c',
'locale-util.c',
#include "sd-id128.h"
#include "io-util.h"
+#include "iovec-wrapper.h"
#include "time-util.h"
/* Make sure not to make this smaller than the maximum coredump size.
#include "format-util.h"
#include "io-util.h"
#include "iovec-util.h"
+#include "iovec-wrapper.h"
#include "log.h"
#include "process-util.h"
#include "string-util.h"