]>
Commit | Line | Data |
---|---|---|
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 |
7 | static const uint8_t nul_byte = 0; |
8 | ||
9 | const struct iovec iovec_nul_byte = { | |
10 | .iov_base = (void*) &nul_byte, | |
11 | .iov_len = 1, | |
12 | }; | |
13 | ||
14 | const struct iovec iovec_empty = { | |
15 | .iov_base = (void*) &nul_byte, | |
16 | .iov_len = 0, | |
17 | }; | |
18 | ||
1ca0b482 | 19 | size_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 |
30 | bool 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 |
55 | struct 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 | ||
62 | void 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 |
69 | char* 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 | ||
81 | char* 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 |
92 | void 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 |
101 | int 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 | ||
112 | struct 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 |
128 | struct 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 | } |