summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-05-21 17:52:14 +0200
committerGitHub <noreply@github.com>2021-05-21 17:52:14 +0200
commit2c80660557ea20864fc23bd610debd6e68ca6b05 (patch)
tree25fc6346e04d79978655c5d99ca91602803e62dc /src
parentMerge pull request #19647 from ddstreet/test-oomd-failure (diff)
parentsysv-generator: use strextend_with_separator() (diff)
downloadsystemd-2c80660557ea20864fc23bd610debd6e68ca6b05.tar.xz
systemd-2c80660557ea20864fc23bd610debd6e68ca6b05.zip
Merge pull request #19672 from yuwata/strextend
tree-wide: introduce strextendf_with_separator() and use strextend() or freinds
Diffstat (limited to 'src')
-rw-r--r--src/basic/env-util.c15
-rw-r--r--src/basic/string-util.c31
-rw-r--r--src/basic/string-util.h4
-rw-r--r--src/core/dbus-util.c6
-rw-r--r--src/escape/escape.c7
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c8
-rw-r--r--src/network/networkctl.c9
-rw-r--r--src/network/networkd-route.c12
-rw-r--r--src/nspawn/nspawn-mount.c39
-rw-r--r--src/run/run.c11
-rw-r--r--src/systemctl/systemctl-show.c9
-rw-r--r--src/sysv-generator/sysv-generator.c33
-rw-r--r--src/test/test-string-util.c14
13 files changed, 76 insertions, 122 deletions
diff --git a/src/basic/env-util.c b/src/basic/env-util.c
index 0e8c2878d6..81b1e3f10e 100644
--- a/src/basic/env-util.c
+++ b/src/basic/env-util.c
@@ -572,12 +572,9 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
t = strv_env_get_n(env, word+2, e-word-2, flags);
- k = strjoin(r, t);
- if (!k)
+ if (!strextend(&r, t))
return NULL;
- free_and_replace(r, k);
-
word = e+1;
state = WORD;
} else if (*e == ':') {
@@ -627,12 +624,9 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
else if (!t && state == DEFAULT_VALUE)
t = v = replace_env_n(test_value, e-test_value, env, flags);
- k = strjoin(r, t);
- if (!k)
+ if (!strextend(&r, t))
return NULL;
- free_and_replace(r, k);
-
word = e+1;
state = WORD;
}
@@ -646,12 +640,9 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
t = strv_env_get_n(env, word+1, e-word-1, flags);
- k = strjoin(r, t);
- if (!k)
+ if (!strextend(&r, t))
return NULL;
- free_and_replace(r, k);
-
word = e--;
i--;
state = WORD;
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
index fd922b117b..a645958d38 100644
--- a/src/basic/string-util.c
+++ b/src/basic/string-util.c
@@ -790,8 +790,8 @@ char *strextend_with_separator_internal(char **x, const char *separator, ...) {
return p;
}
-int strextendf(char **x, const char *format, ...) {
- size_t m, a;
+int strextendf_with_separator(char **x, const char *separator, const char *format, ...) {
+ size_t m, a, l_separator;
va_list ap;
int l;
@@ -802,6 +802,8 @@ int strextendf(char **x, const char *format, ...) {
assert(x);
assert(format);
+ l_separator = isempty(*x) ? 0 : strlen_ptr(separator);
+
/* Let's try to use the allocated buffer, if there's room at the end still. Otherwise let's extend by 64 chars. */
if (*x) {
m = strlen(*x);
@@ -810,13 +812,15 @@ int strextendf(char **x, const char *format, ...) {
} else
m = a = 0;
- if (a - m < 17) { /* if there's less than 16 chars space, then enlarge the buffer first */
+ if (a - m < 17 + l_separator) { /* if there's less than 16 chars space, then enlarge the buffer first */
char *n;
- if (_unlikely_(m > SIZE_MAX - 64)) /* overflow check */
+ if (_unlikely_(l_separator > SIZE_MAX - 64)) /* overflow check #1 */
+ return -ENOMEM;
+ if (_unlikely_(m > SIZE_MAX - 64 - l_separator)) /* overflow check #2 */
return -ENOMEM;
- n = realloc(*x, m + 64);
+ n = realloc(*x, m + 64 + l_separator);
if (!n)
return -ENOMEM;
@@ -825,19 +829,20 @@ int strextendf(char **x, const char *format, ...) {
}
/* Now, let's try to format the string into it */
+ memcpy_safe(*x + m, separator, l_separator);
va_start(ap, format);
- l = vsnprintf(*x + m, a - m, format, ap);
+ l = vsnprintf(*x + m + l_separator, a - m - l_separator, format, ap);
va_end(ap);
assert(l >= 0);
- if ((size_t) l < a - m) {
+ if ((size_t) l < a - m - l_separator) {
char *n;
/* Nice! This worked. We are done. But first, let's return the extra space we don't
* need. This should be a cheap operation, since we only lower the allocation size here,
* never increase. */
- n = realloc(*x, m + (size_t) l + 1);
+ n = realloc(*x, m + (size_t) l + l_separator + 1);
if (n)
*x = n;
} else {
@@ -845,22 +850,22 @@ int strextendf(char **x, const char *format, ...) {
/* Wasn't enough. Then let's allocate exactly what we need. */
- if (_unlikely_((size_t) l > SIZE_MAX - 1)) /* overflow check #1 */
+ if (_unlikely_((size_t) l > SIZE_MAX - (l_separator + 1))) /* overflow check #1 */
goto oom;
- if (_unlikely_(m > SIZE_MAX - ((size_t) l + 1))) /* overflow check #2 */
+ if (_unlikely_(m > SIZE_MAX - ((size_t) l + l_separator + 1))) /* overflow check #2 */
goto oom;
- a = m + (size_t) l + 1;
+ a = m + (size_t) l + l_separator + 1;
n = realloc(*x, a);
if (!n)
goto oom;
*x = n;
va_start(ap, format);
- l = vsnprintf(*x + m, a - m, format, ap);
+ l = vsnprintf(*x + m + l_separator, a - m - l_separator, format, ap);
va_end(ap);
- assert((size_t) l < a - m);
+ assert((size_t) l < a - m - l_separator);
}
return 0;
diff --git a/src/basic/string-util.h b/src/basic/string-util.h
index 4ef3254dc5..9155e50ba8 100644
--- a/src/basic/string-util.h
+++ b/src/basic/string-util.h
@@ -156,11 +156,11 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin
char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]);
char *strextend_with_separator_internal(char **x, const char *separator, ...) _sentinel_;
-
#define strextend_with_separator(x, separator, ...) strextend_with_separator_internal(x, separator, __VA_ARGS__, NULL)
#define strextend(x, ...) strextend_with_separator_internal(x, NULL, __VA_ARGS__, NULL)
-int strextendf(char **x, const char *format, ...) _printf_(2,3);
+int strextendf_with_separator(char **x, const char *separator, const char *format, ...) _printf_(3,4);
+#define strextendf(x, ...) strextendf_with_separator(x, NULL, __VA_ARGS__)
char *strrep(const char *s, unsigned n);
diff --git a/src/core/dbus-util.c b/src/core/dbus-util.c
index 44a2ccfca0..ca9b399d8c 100644
--- a/src/core/dbus-util.c
+++ b/src/core/dbus-util.c
@@ -181,7 +181,7 @@ int bus_read_mount_options(
return r;
while ((r = sd_bus_message_read(message, "(ss)", &partition, &mount_options)) > 0) {
- _cleanup_free_ char *previous = NULL, *escaped = NULL;
+ _cleanup_free_ char *escaped = NULL;
_cleanup_free_ MountOptions *o = NULL;
PartitionDesignator partition_designator;
@@ -198,9 +198,7 @@ int bus_read_mount_options(
if (!escaped)
return -ENOMEM;
- previous = TAKE_PTR(format_str);
- format_str = strjoin(previous, previous ? separator : "", partition, ":", escaped);
- if (!format_str)
+ if (!strextend_with_separator(&format_str, separator, partition, ":", escaped))
return -ENOMEM;
o = new(MountOptions, 1);
diff --git a/src/escape/escape.c b/src/escape/escape.c
index 3178f9b172..1575a68410 100644
--- a/src/escape/escape.c
+++ b/src/escape/escape.c
@@ -188,13 +188,8 @@ static int run(int argc, char *argv[]) {
free_and_replace(e, x);
} else if (arg_suffix) {
- char *x;
-
- x = strjoin(e, ".", arg_suffix);
- if (!x)
+ if (!strextend(&e, ".", arg_suffix))
return log_oom();
-
- free_and_replace(e, x);
}
break;
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 0ec0d8d26e..090288af0d 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -1574,18 +1574,12 @@ int bus_set_address_machine(sd_bus *b, bool user, const char *machine) {
return -ENOMEM;
if (user) {
- char *k;
-
/* Ideally we'd use the "--user" switch to systemd-stdio-bridge here, but it's only
* available in recent systemd versions. Using the "-p" switch with the explicit path
* is a working alternative, and is compatible with older versions, hence that's what
* we use here. */
-
- k = strjoin(a, ",argv7=-punix:path%3d%24%7bXDG_RUNTIME_DIR%7d/bus");
- if (!k)
+ if (!strextend(&a, ",argv7=-punix:path%3d%24%7bXDG_RUNTIME_DIR%7d/bus"))
return -ENOMEM;
-
- free_and_replace(a, k);
}
} else {
_cleanup_free_ char *e = NULL;
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index b4e3bfc7ae..9d3e3f033b 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -1046,26 +1046,25 @@ static int dump_gateways(
return n;
for (int i = 0; i < n; i++) {
- _cleanup_free_ char *gateway = NULL, *description = NULL, *with_description = NULL;
+ _cleanup_free_ char *gateway = NULL, *description = NULL;
char name[IF_NAMESIZE+1];
r = in_addr_to_string(local[i].family, &local[i].address, &gateway);
if (r < 0)
- return r;
+ return log_oom();
r = get_gateway_description(rtnl, hwdb, local[i].ifindex, local[i].family, &local[i].address, &description);
if (r < 0)
log_debug_errno(r, "Could not get description of gateway, ignoring: %m");
if (description) {
- with_description = strjoin(gateway, " (", description, ")");
- if (!with_description)
+ if (!strextend(&gateway, " (", description, ")"))
return log_oom();
}
/* Show interface name for the entry if we show entries for all interfaces */
r = strv_extendf(&buf, "%s%s%s",
- with_description ?: gateway,
+ gateway,
ifindex <= 0 ? " on " : "",
ifindex <= 0 ? format_ifname_full(local[i].ifindex, name, FORMAT_IFNAME_IFINDEX_WITH_PERCENT) : "");
if (r < 0)
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 60eef08074..a5382e42ab 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -773,13 +773,17 @@ static void log_route_debug(const Route *route, const char *str, const Link *lin
MultipathRoute *m;
ORDERED_SET_FOREACH(m, route->multipath_routes) {
- _cleanup_free_ char *buf = NULL, *joined = NULL;
+ _cleanup_free_ char *buf = NULL;
union in_addr_union a = m->gateway.address;
(void) in_addr_to_string(m->gateway.family, &a, &buf);
- joined = strjoin(gw_alloc, gw_alloc ? "," : "", strna(buf), m->ifname ? "@" : "", strempty(m->ifname));
- if (joined)
- free_and_replace(gw_alloc, joined);
+ (void) strextend_with_separator(&gw_alloc, ",", strna(buf));
+ if (m->ifname)
+ (void) strextend(&gw_alloc, "@", m->ifname);
+ else if (m->ifindex > 0)
+ (void) strextendf(&gw_alloc, "@%"PRIu32, m->ifindex);
+ /* See comments in config_parse_multipath_route(). */
+ (void) strextendf(&gw_alloc, ":%"PRIu32, m->weight + 1);
}
gw = gw_alloc;
}
diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c
index dbebc49ae7..c28e429935 100644
--- a/src/nspawn/nspawn-mount.c
+++ b/src/nspawn/nspawn-mount.c
@@ -382,39 +382,28 @@ int tmpfs_patch_options(
const char *selinux_apifs_context,
char **ret) {
- char *buf = NULL;
+ _cleanup_free_ char *buf = NULL;
- if (uid_shift != UID_INVALID) {
- if (asprintf(&buf, "%s%suid=" UID_FMT ",gid=" UID_FMT,
- strempty(options), options ? "," : "",
- uid_shift, uid_shift) < 0)
- return -ENOMEM;
+ assert(ret);
- options = buf;
+ if (options) {
+ buf = strdup(options);
+ if (!buf)
+ return -ENOMEM;
}
-#if HAVE_SELINUX
- if (selinux_apifs_context) {
- char *t;
-
- t = strjoin(strempty(options), options ? "," : "",
- "context=\"", selinux_apifs_context, "\"");
- free(buf);
- if (!t)
+ if (uid_shift != UID_INVALID)
+ if (strextendf_with_separator(&buf, ",", "uid=" UID_FMT ",gid=" UID_FMT, uid_shift, uid_shift) < 0)
return -ENOMEM;
- buf = t;
- }
-#endif
-
- if (!buf && options) {
- buf = strdup(options);
- if (!buf)
+#if HAVE_SELINUX
+ if (selinux_apifs_context)
+ if (!strextend_with_separator(&buf, ",", "context=\"", selinux_apifs_context, "\""))
return -ENOMEM;
- }
- *ret = buf;
+#endif
- return !!buf;
+ *ret = TAKE_PTR(buf);
+ return !!*ret;
}
int mount_sysfs(const char *dest, MountSettingsMask mount_settings) {
diff --git a/src/run/run.c b/src/run/run.c
index 555f0584c8..38de0322e0 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -667,15 +667,8 @@ static int transient_cgroup_set_properties(sd_bus_message *m) {
*end = 0;
}
- if (!isempty(arg_slice)) {
- if (name) {
- char *j = strjoin(name, "-", arg_slice);
- free_and_replace(name, j);
- } else
- name = strdup(arg_slice);
- if (!name)
- return log_oom();
- }
+ if (!isempty(arg_slice) && !strextend_with_separator(&name, "-", arg_slice))
+ return log_oom();
if (!name)
return 0;
diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c
index a45f5fa363..3686ac3c76 100644
--- a/src/systemctl/systemctl-show.c
+++ b/src/systemctl/systemctl-show.c
@@ -1659,14 +1659,9 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
if (r < 0)
return r;
- while ((r = sd_bus_message_read(m, "(ss)", &partition, &mount_options)) > 0) {
- _cleanup_free_ char *previous = NULL;
-
- previous = TAKE_PTR(str);
- str = strjoin(strempty(previous), previous ? ":" : "", partition, ":", mount_options);
- if (!str)
+ while ((r = sd_bus_message_read(m, "(ss)", &partition, &mount_options)) > 0)
+ if (!strextend_with_separator(&str, ":", partition, ":", mount_options))
return log_oom();
- }
if (r < 0)
return r;
diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
index cef141fbac..bf23c48662 100644
--- a/src/sysv-generator/sysv-generator.c
+++ b/src/sysv-generator/sysv-generator.c
@@ -533,7 +533,7 @@ static int load_sysv(SysvStub *s) {
* continuation */
size_t k;
- char *j;
+ const char *j;
k = strlen(t);
if (k > 0 && t[k-1] == '\\')
@@ -542,19 +542,8 @@ static int load_sysv(SysvStub *s) {
state = NORMAL;
j = strstrip(t);
- if (!isempty(j)) {
- char *d = NULL;
-
- if (chkconfig_description)
- d = strjoin(chkconfig_description, " ", j);
- else
- d = strdup(j);
- if (!d)
- return log_oom();
-
- free(chkconfig_description);
- chkconfig_description = d;
- }
+ if (!isempty(j) && !strextend_with_separator(&chkconfig_description, " ", j))
+ return log_oom();
} else if (IN_SET(state, LSB, LSB_DESCRIPTION)) {
@@ -604,20 +593,8 @@ static int load_sysv(SysvStub *s) {
const char *j;
j = strstrip(t);
- if (!isempty(j)) {
- char *d = NULL;
-
- if (long_description)
- d = strjoin(long_description, " ", t);
- else
- d = strdup(j);
- if (!d)
- return log_oom();
-
- free(long_description);
- long_description = d;
- }
-
+ if (!isempty(j) && !strextend_with_separator(&long_description, " ", j))
+ return log_oom();
} else
state = LSB;
}
diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c
index 8174b12837..4d9d0260c9 100644
--- a/src/test/test-string-util.c
+++ b/src/test/test-string-util.c
@@ -984,6 +984,20 @@ static void test_strextendf(void) {
assert_se(strextendf(&p, "<%08x>", 0x1234) >= 0);
assert_se(streq(p, "<77><99>< 88><00001234>"));
+
+ p = mfree(p);
+
+ assert_se(strextendf_with_separator(&p, ",", "<%i>", 77) >= 0);
+ assert_se(streq(p, "<77>"));
+
+ assert_se(strextendf_with_separator(&p, ",", "<%i>", 99) >= 0);
+ assert_se(streq(p, "<77>,<99>"));
+
+ assert_se(strextendf_with_separator(&p, ",", "<%80i>", 88) >= 0);
+ assert_se(streq(p, "<77>,<99>,< 88>"));
+
+ assert_se(strextendf_with_separator(&p, ",", "<%08x>", 0x1234) >= 0);
+ assert_se(streq(p, "<77>,<99>,< 88>,<00001234>"));
}
int main(int argc, char *argv[]) {