]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/strxcpyx.c
udev: tag MTD devices for systemd
[thirdparty/systemd.git] / src / basic / strxcpyx.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
d5a89d7d
KS
2
3/*
4 * Concatenates/copies strings. In any case, terminates in all cases
9e5bd85a
VC
5 * with '\0' and moves the @dest pointer forward to the added '\0'.
6 * Returns the remaining size, and 0 if the string was truncated.
7 *
8 * Due to the intended usage, these helpers silently noop invocations
9 * having zero size. This is technically an exception to the above
10 * statement "terminates in all cases". It's unexpected for such calls to
11 * occur outside of a loop where this is the preferred behavior.
d5a89d7d
KS
12 */
13
11c3a366 14#include <stdarg.h>
d5a89d7d
KS
15#include <stdio.h>
16#include <string.h>
cf0fbc49 17
e70151c9 18#include "string-util.h"
d5a89d7d
KS
19#include "strxcpyx.h"
20
e70151c9
YW
21size_t strnpcpy_full(char **dest, size_t size, const char *src, size_t len, bool *ret_truncated) {
22 bool truncated = false;
23
f91049d5
VC
24 assert(dest);
25 assert(src);
26
e70151c9
YW
27 if (size == 0) {
28 if (ret_truncated)
29 *ret_truncated = len > 0;
9e5bd85a 30 return 0;
e70151c9 31 }
9e5bd85a 32
d5a89d7d
KS
33 if (len >= size) {
34 if (size > 1)
35 *dest = mempcpy(*dest, src, size-1);
36 size = 0;
e70151c9 37 truncated = true;
68619204
LP
38 } else if (len > 0) {
39 *dest = mempcpy(*dest, src, len);
40 size -= len;
d5a89d7d 41 }
68619204 42
e70151c9
YW
43 if (ret_truncated)
44 *ret_truncated = truncated;
45
d5a89d7d
KS
46 *dest[0] = '\0';
47 return size;
48}
49
e70151c9 50size_t strpcpy_full(char **dest, size_t size, const char *src, bool *ret_truncated) {
7e4831d2
YW
51 assert(dest);
52 assert(src);
53
e70151c9 54 return strnpcpy_full(dest, size, src, strlen(src), ret_truncated);
7e4831d2
YW
55}
56
e70151c9
YW
57size_t strpcpyf_full(char **dest, size_t size, bool *ret_truncated, const char *src, ...) {
58 bool truncated = false;
d5a89d7d
KS
59 va_list va;
60 int i;
61
f91049d5
VC
62 assert(dest);
63 assert(src);
64
d5a89d7d
KS
65 va_start(va, src);
66 i = vsnprintf(*dest, size, src, va);
e70151c9
YW
67 va_end(va);
68
69 if (i < (int) size) {
d5a89d7d
KS
70 *dest += i;
71 size -= i;
e70151c9 72 } else {
d5a89d7d 73 size = 0;
e70151c9
YW
74 truncated = i > 0;
75 }
76
77 if (ret_truncated)
78 *ret_truncated = truncated;
79
d5a89d7d
KS
80 return size;
81}
82
e70151c9
YW
83size_t strpcpyl_full(char **dest, size_t size, bool *ret_truncated, const char *src, ...) {
84 bool truncated = false;
d5a89d7d
KS
85 va_list va;
86
f91049d5
VC
87 assert(dest);
88 assert(src);
89
d5a89d7d
KS
90 va_start(va, src);
91 do {
e70151c9
YW
92 bool t;
93
94 size = strpcpy_full(dest, size, src, &t);
95 truncated = truncated || t;
d5a89d7d 96 src = va_arg(va, char *);
68619204 97 } while (src);
d5a89d7d 98 va_end(va);
e70151c9
YW
99
100 if (ret_truncated)
101 *ret_truncated = truncated;
d5a89d7d
KS
102 return size;
103}
104
e70151c9 105size_t strnscpy_full(char *dest, size_t size, const char *src, size_t len, bool *ret_truncated) {
d5a89d7d
KS
106 char *s;
107
f91049d5
VC
108 assert(dest);
109 assert(src);
110
d5a89d7d 111 s = dest;
e70151c9 112 return strnpcpy_full(&s, size, src, len, ret_truncated);
7e4831d2
YW
113}
114
e70151c9 115size_t strscpy_full(char *dest, size_t size, const char *src, bool *ret_truncated) {
7e4831d2
YW
116 assert(dest);
117 assert(src);
118
e70151c9 119 return strnscpy_full(dest, size, src, strlen(src), ret_truncated);
d5a89d7d
KS
120}
121
e70151c9
YW
122size_t strscpyl_full(char *dest, size_t size, bool *ret_truncated, const char *src, ...) {
123 bool truncated = false;
d5a89d7d
KS
124 va_list va;
125 char *s;
126
f91049d5
VC
127 assert(dest);
128 assert(src);
129
d5a89d7d
KS
130 va_start(va, src);
131 s = dest;
132 do {
e70151c9
YW
133 bool t;
134
135 size = strpcpy_full(&s, size, src, &t);
136 truncated = truncated || t;
d5a89d7d 137 src = va_arg(va, char *);
68619204 138 } while (src);
d5a89d7d
KS
139 va_end(va);
140
e70151c9
YW
141 if (ret_truncated)
142 *ret_truncated = truncated;
143
d5a89d7d
KS
144 return size;
145}