diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-05-21 17:52:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-21 17:52:14 +0200 |
commit | 2c80660557ea20864fc23bd610debd6e68ca6b05 (patch) | |
tree | 25fc6346e04d79978655c5d99ca91602803e62dc /src | |
parent | Merge pull request #19647 from ddstreet/test-oomd-failure (diff) | |
parent | sysv-generator: use strextend_with_separator() (diff) | |
download | systemd-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.c | 15 | ||||
-rw-r--r-- | src/basic/string-util.c | 31 | ||||
-rw-r--r-- | src/basic/string-util.h | 4 | ||||
-rw-r--r-- | src/core/dbus-util.c | 6 | ||||
-rw-r--r-- | src/escape/escape.c | 7 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/sd-bus.c | 8 | ||||
-rw-r--r-- | src/network/networkctl.c | 9 | ||||
-rw-r--r-- | src/network/networkd-route.c | 12 | ||||
-rw-r--r-- | src/nspawn/nspawn-mount.c | 39 | ||||
-rw-r--r-- | src/run/run.c | 11 | ||||
-rw-r--r-- | src/systemctl/systemctl-show.c | 9 | ||||
-rw-r--r-- | src/sysv-generator/sysv-generator.c | 33 | ||||
-rw-r--r-- | src/test/test-string-util.c | 14 |
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[]) { |