diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-10-19 16:24:20 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2023-10-20 10:43:50 +0200 |
commit | ea1f38146a3d3e2d2217e1430ab6874ea0281abe (patch) | |
tree | 5984a4d2399485b88a09195eb13f158d2d80c925 /src | |
parent | iovec-util: make IOVEC_INCREMENT a regular function too (diff) | |
download | systemd-ea1f38146a3d3e2d2217e1430ab6874ea0281abe.tar.xz systemd-ea1f38146a3d3e2d2217e1430ab6874ea0281abe.zip |
io-util: split out iovw_xyz into iovec-wrapper.h
Let's split these APIs out, they are kinda their own thing.
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/io-util.c | 108 | ||||
-rw-r--r-- | src/basic/io-util.h | 36 | ||||
-rw-r--r-- | src/basic/iovec-wrapper.c | 131 | ||||
-rw-r--r-- | src/basic/iovec-wrapper.h | 42 | ||||
-rw-r--r-- | src/basic/meson.build | 3 | ||||
-rw-r--r-- | src/shared/journal-importer.h | 1 | ||||
-rw-r--r-- | src/test/test-log.c | 1 |
7 files changed, 177 insertions, 145 deletions
diff --git a/src/basic/io-util.c b/src/basic/io-util.c index eda4f1fac3..ede959fabc 100644 --- a/src/basic/io-util.c +++ b/src/basic/io-util.c @@ -305,111 +305,3 @@ ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) { 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; -} diff --git a/src/basic/io-util.h b/src/basic/io-util.h index 45278fbde9..e027c1a878 100644 --- a/src/basic/io-util.h +++ b/src/basic/io-util.h @@ -6,7 +6,6 @@ #include <stddef.h> #include <stdint.h> #include <sys/types.h> -#include <sys/uio.h> #include "macro.h" #include "time-util.h" @@ -45,38 +44,3 @@ static inline bool FILE_SIZE_VALID_OR_INFINITY(uint64_t l) { 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); diff --git a/src/basic/iovec-wrapper.c b/src/basic/iovec-wrapper.c new file mode 100644 index 0000000000..b335acd108 --- /dev/null +++ b/src/basic/iovec-wrapper.c @@ -0,0 +1,131 @@ +/* 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; +} diff --git a/src/basic/iovec-wrapper.h b/src/basic/iovec-wrapper.h new file mode 100644 index 0000000000..05e220c1d0 --- /dev/null +++ b/src/basic/iovec-wrapper.h @@ -0,0 +1,42 @@ +/* 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); diff --git a/src/basic/meson.build b/src/basic/meson.build index a06931c863..438e8493b8 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -44,8 +44,9 @@ basic_sources = files( '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', diff --git a/src/shared/journal-importer.h b/src/shared/journal-importer.h index 6cbac4c4e1..d84dcc4bb0 100644 --- a/src/shared/journal-importer.h +++ b/src/shared/journal-importer.h @@ -9,6 +9,7 @@ #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. diff --git a/src/test/test-log.c b/src/test/test-log.c index 28acb3fb8a..b0363c612a 100644 --- a/src/test/test-log.c +++ b/src/test/test-log.c @@ -6,6 +6,7 @@ #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" |