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:
parent
986235a99a
commit
ea1f38146a
@ -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;
|
||||
}
|
||||
|
@ -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
131
src/basic/iovec-wrapper.c
Normal 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
42
src/basic/iovec-wrapper.h
Normal 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);
|
@ -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',
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user