From: Zbigniew Jędrzejewski-Szmek Date: Fri, 15 Mar 2024 12:16:51 +0000 (+0100) Subject: src/basic: add yet another strdup helper X-Git-Tag: v256-rc1~459^2~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=892c5902ae11e5b0ca0494411067794d763baf45;p=thirdparty%2Fsystemd.git src/basic: add yet another strdup helper It's a bit ugly to have both strdup_to() and strdup_to_full(). I initially started with one variant, but then in some functions we want the additional info, while in many other places, having 1 instead of 0 causes the return value of whole chains of functions to be changed. It *probably* wouldn't cause any difference, but there is at least of bunch of tests that would need to be updated, so in the end it seems to have the two variants. The output param is first to match free_and_strdup() and other similar functions. --- diff --git a/src/basic/string-util.c b/src/basic/string-util.c index c1e7e6e6224..6e8d10747b6 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -1126,6 +1126,24 @@ int free_and_strndup(char **p, const char *s, size_t l) { return 1; } +int strdup_to_full(char **ret, const char *src) { + if (!src) { + if (ret) + *ret = NULL; + + return 0; + } else { + if (ret) { + char *t = strdup(src); + if (!t) + return -ENOMEM; + *ret = t; + } + + return 1; + } +}; + bool string_is_safe(const char *p) { if (!p) return false; diff --git a/src/basic/string-util.h b/src/basic/string-util.h index e162765aa71..c402cd3af04 100644 --- a/src/basic/string-util.h +++ b/src/basic/string-util.h @@ -224,6 +224,12 @@ static inline int free_and_strdup_warn(char **p, const char *s) { } int free_and_strndup(char **p, const char *s, size_t l); +int strdup_to_full(char **ret, const char *src); +static inline int strdup_to(char **ret, const char *src) { + int r = strdup_to_full(ASSERT_PTR(ret), src); + return r < 0 ? r : 0; /* Suppress return value of 1. */ +} + bool string_is_safe(const char *p) _pure_; DISABLE_WARNING_STRINGOP_TRUNCATION; diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c index 92f1083a4c5..3b003e885f0 100644 --- a/src/test/test-string-util.c +++ b/src/test/test-string-util.c @@ -88,6 +88,35 @@ TEST(free_and_strndup) { } } +TEST(strdup_to_full) { + _cleanup_free_ char *dst; + + assert_se(strdup_to_full(NULL, NULL) == 0); + assert_se(strdup_to_full(&dst, NULL) == 0); + + assert_se(strdup_to_full(NULL, "") == 1); + assert_se(strdup_to_full(&dst, "") == 1); + assert_se(streq_ptr(dst, "")); + dst = mfree(dst); + + assert_se(strdup_to_full(NULL, "x") == 1); + assert_se(strdup_to_full(&dst, "x") == 1); + assert_se(streq_ptr(dst, "x")); +} + +TEST(strdup_to) { + _cleanup_free_ char *dst; + + assert_se(strdup_to(&dst, NULL) == 0); + + assert_se(strdup_to(&dst, "") == 0); + assert_se(streq_ptr(dst, "")); + dst = mfree(dst); + + assert_se(strdup_to(&dst, "x") == 0); + assert_se(streq_ptr(dst, "x")); +} + TEST(ascii_strcasecmp_n) { assert_se(ascii_strcasecmp_n("", "", 0) == 0); assert_se(ascii_strcasecmp_n("", "", 1) == 0);