]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
src/basic: add yet another strdup helper
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 15 Mar 2024 12:16:51 +0000 (13:16 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 20 Mar 2024 14:12:12 +0000 (15:12 +0100)
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.

src/basic/string-util.c
src/basic/string-util.h
src/test/test-string-util.c

index c1e7e6e62248b4cb371af8ced124890854150b56..6e8d10747b60fe840d70e9a480b94e8b50ef9083 100644 (file)
@@ -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;
index e162765aa7174a8113952e2b606b5c22b09cb482..c402cd3af045c55d6a8dc3fa48bc6025d53bc703 100644 (file)
@@ -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;
index 92f1083a4c5047b2958fea1f17dfcef216ae91fc..3b003e885f0d3af249d40b0014c3a1674f068cc4 100644 (file)
@@ -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);