]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/iovec-util.c
man/systemd-sysext: list ephemeral/ephemeral-import in the list of options
[thirdparty/systemd.git] / src / basic / iovec-util.c
CommitLineData
bd1ae178
LP
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
e53d4f34 3#include "alloc-util.h"
bd1ae178
LP
4#include "iovec-util.h"
5#include "string-util.h"
6
432977a0
LP
7static const uint8_t nul_byte = 0;
8
9const struct iovec iovec_nul_byte = {
10 .iov_base = (void*) &nul_byte,
11 .iov_len = 1,
12};
13
14const struct iovec iovec_empty = {
15 .iov_base = (void*) &nul_byte,
16 .iov_len = 0,
17};
18
1ca0b482 19size_t iovec_total_size(const struct iovec *iovec, size_t n) {
c24e0dbe
LP
20 size_t sum = 0;
21
1ca0b482 22 assert(iovec || n == 0);
c24e0dbe 23
1ca0b482 24 FOREACH_ARRAY(j, iovec, n)
c24e0dbe
LP
25 sum += j->iov_len;
26
27 return sum;
28}
bd1ae178 29
1ca0b482
ZJS
30bool iovec_increment(struct iovec *iovec, size_t n, size_t k) {
31 assert(iovec || n == 0);
986235a9
LP
32
33 /* Returns true if there is nothing else to send (bytes written cover all of the iovec),
34 * false if there's still work to do. */
35
1ca0b482 36 FOREACH_ARRAY(j, iovec, n) {
986235a9
LP
37 size_t sub;
38
39 if (j->iov_len == 0)
40 continue;
41 if (k == 0)
42 return false;
43
44 sub = MIN(j->iov_len, k);
45 j->iov_len -= sub;
46 j->iov_base = (uint8_t*) j->iov_base + sub;
47 k -= sub;
48 }
49
50 assert(k == 0); /* Anything else would mean that we wrote more bytes than available,
51 * or the kernel reported writing more bytes than sent. */
52 return true;
53}
54
e53d4f34
DDM
55struct iovec* iovec_make_string(struct iovec *iovec, const char *s) {
56 assert(iovec);
57
58 *iovec = IOVEC_MAKE(s, strlen_ptr(s));
59 return iovec;
60}
61
62void iovec_done_erase(struct iovec *iovec) {
63 assert(iovec);
64
65 iovec->iov_base = erase_and_free(iovec->iov_base);
66 iovec->iov_len = 0;
67}
68
bd1ae178
LP
69char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value) {
70 char *x;
71
72 assert(iovec);
73 assert(n_iovec);
74
75 x = strjoin(field, value);
76 if (x)
77 iovec[(*n_iovec)++] = IOVEC_MAKE_STRING(x);
78 return x;
79}
80
81char* set_iovec_string_field_free(struct iovec *iovec, size_t *n_iovec, const char *field, char *value) {
82 char *x;
83
84 assert(iovec);
85 assert(n_iovec);
86
87 x = set_iovec_string_field(iovec, n_iovec, field, value);
88 free(value);
89 return x;
90}
91
ba354c16
MY
92void iovec_array_free(struct iovec *iovec, size_t n_iovec) {
93 assert(iovec || n_iovec == 0);
94
95 FOREACH_ARRAY(i, iovec, n_iovec)
1dd33bf3 96 free(i->iov_base);
bd1ae178 97
1ca0b482 98 free(iovec);
bd1ae178 99}
664570f5 100
e53d4f34
DDM
101int iovec_memcmp(const struct iovec *a, const struct iovec *b) {
102
103 if (a == b)
104 return 0;
105
106 return memcmp_nn(a ? a->iov_base : NULL,
107 a ? a->iov_len : 0,
108 b ? b->iov_base : NULL,
109 b ? b->iov_len : 0);
110}
111
112struct iovec* iovec_memdup(const struct iovec *source, struct iovec *ret) {
113 assert(ret);
114
115 if (!iovec_is_set(source))
116 *ret = (struct iovec) {};
117 else {
118 void *p = memdup(source->iov_base, source->iov_len);
119 if (!p)
120 return NULL;
121
122 *ret = IOVEC_MAKE(p, source->iov_len);
123 }
124
125 return ret;
126}
127
664570f5
LP
128struct iovec* iovec_append(struct iovec *iovec, const struct iovec *append) {
129 assert(iovec_is_valid(iovec));
130
131 if (!iovec_is_set(append))
132 return iovec;
133
134 if (!greedy_realloc_append(&iovec->iov_base, &iovec->iov_len, append->iov_base, append->iov_len, 1))
135 return NULL;
136
137 return iovec;
138}