1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-18 10:04:04 +03:00

io-util: split out iovw_xyz into iovec-wrapper.h

Let's split these APIs out, they are kinda their own thing.
This commit is contained in:
Lennart Poettering 2023-10-19 16:24:20 +02:00
parent 986235a99a
commit ea1f38146a
7 changed files with 177 additions and 145 deletions

View File

@ -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;
}

View File

@ -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);

131
src/basic/iovec-wrapper.c Normal file
View File

@ -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;
}

42
src/basic/iovec-wrapper.h Normal file
View File

@ -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);

View File

@ -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',

View File

@ -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.

View File

@ -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"