From: Zbigniew Jędrzejewski-Szmek Date: Mon, 13 Apr 2026 19:41:32 +0000 (+0200) Subject: basic/iovec-wrapper: add iovw_append and iovw_to_cstring X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f32af5c69ab71176a70c187b380e9689de834fc4;p=thirdparty%2Fsystemd.git basic/iovec-wrapper: add iovw_append and iovw_to_cstring Existing iovw_append is renamed to iovw_append_iovw. iovw_consume is made noninline. --- diff --git a/src/basic/iovec-wrapper.c b/src/basic/iovec-wrapper.c index 7f91f5e893b..408985763ea 100644 --- a/src/basic/iovec-wrapper.c +++ b/src/basic/iovec-wrapper.c @@ -41,6 +41,28 @@ int iovw_put(struct iovec_wrapper *iovw, void *data, size_t len) { return 0; } +int iovw_append(struct iovec_wrapper *iovw, const void *data, size_t len) { + if (len == 0) + return 0; + + void *c = memdup(data, len); + if (!c) + return -ENOMEM; + + return iovw_put(iovw, c, len); +} + +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; +} + int iovw_put_string_field_full(struct iovec_wrapper *iovw, bool replace, const char *field, const char *value) { _cleanup_free_ char *x = NULL; int r; @@ -103,7 +125,7 @@ size_t iovw_size(const struct iovec_wrapper *iovw) { return iovec_total_size(iovw->iovec, iovw->count); } -int iovw_append(struct iovec_wrapper *target, const struct iovec_wrapper *source) { +int iovw_append_iovw(struct iovec_wrapper *target, const struct iovec_wrapper *source) { size_t original_count; int r; @@ -139,3 +161,32 @@ rollback: target->count = original_count; return r; } + +char* iovw_to_cstring(const struct iovec_wrapper *iovw) { + size_t size; + char *p, *ans; + + assert(iovw); + + /* Squish a series of iovecs into a C string. Embedded NULs are not allowed. + * The caller is expected to filter them out when populating the data. */ + + size = iovw_size(iovw); + if (size == SIZE_MAX) + return NULL; /* Prevent theoretical overflow */ + size ++; + + p = ans = new(char, size); + if (!ans) + return NULL; + + FOREACH_ARRAY(iovec, iovw->iovec, iovw->count) { + assert(!memchr(iovec->iov_base, 0, iovec->iov_len)); + + p = mempcpy(p, iovec->iov_base, iovec->iov_len); + } + + *p = '\0'; + + return ans; +} diff --git a/src/basic/iovec-wrapper.h b/src/basic/iovec-wrapper.h index bfe739ecf1e..6f0c9af43c9 100644 --- a/src/basic/iovec-wrapper.h +++ b/src/basic/iovec-wrapper.h @@ -12,16 +12,8 @@ void iovw_done_free(struct iovec_wrapper *iovw); void iovw_done(struct iovec_wrapper *iovw); 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; -} +int iovw_append(struct iovec_wrapper *iovw, const void *data, size_t len); +int iovw_consume(struct iovec_wrapper *iovw, void *data, size_t len); static inline bool iovw_isempty(const struct iovec_wrapper *iovw) { return !iovw || iovw->count == 0; @@ -40,4 +32,5 @@ int iovw_put_string_fieldf_full(struct iovec_wrapper *iovw, bool replace, const 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); +int iovw_append_iovw(struct iovec_wrapper *target, const struct iovec_wrapper *source); +char* iovw_to_cstring(const struct iovec_wrapper *iovw); diff --git a/src/coredump/coredump-backtrace.c b/src/coredump/coredump-backtrace.c index 0a2dec23136..b8aa880f8e4 100644 --- a/src/coredump/coredump-backtrace.c +++ b/src/coredump/coredump-backtrace.c @@ -50,7 +50,7 @@ int coredump_backtrace(int argc, char *argv[]) { } else { /* The imported iovecs are not supposed to be freed by us so let's copy and merge them at the * end of the array. */ - r = iovw_append(&context.iovw, &importer.iovw); + r = iovw_append_iovw(&context.iovw, &importer.iovw); if (r < 0) return r; }