[libvirt] [PATCH 1/2] virStrndup: Accept negative values as string length

Michal Privoznik mprivozn at redhat.com
Fri May 24 09:53:08 UTC 2013


It may shorten the code a bit as the following pattern:

  VIR_STRNDUP(dst, src, cond ? n : strlen(src))

is used on several places among our code. However, we can
move the strlen into virStrndup and thus write just:

  VIR_STRNDUP(dst, src, cond ? n : -1)
---
 src/util/virstring.c  |  7 ++++++-
 src/util/virstring.h  | 11 ++++++++---
 tests/virstringtest.c | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/src/util/virstring.c b/src/util/virstring.c
index fcbb375..b244e6c 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -568,12 +568,15 @@ virStrdup(char **dest,
  * caller's body where virStrndup is called from. Consider
  * using VIR_STRNDUP which sets these automatically.
  *
+ * In case @n is smaller than zero, the whole @src string is
+ * copied.
+ *
  * Returns: 0 for NULL src, 1 on successful copy, -1 otherwise.
  */
 int
 virStrndup(char **dest,
            const char *src,
-           size_t n,
+           ssize_t n,
            bool report,
            int domcode,
            const char *filename,
@@ -582,6 +585,8 @@ virStrndup(char **dest,
 {
     if (!src)
         return 0;
+    if (n < 0)
+        n = strlen(src);
     if (!(*dest = strndup(src, n))) {
         if (report)
             virReportOOMErrorFull(domcode, filename, funcname, linenr);
diff --git a/src/util/virstring.h b/src/util/virstring.h
index 534ce91..7063fe4 100644
--- a/src/util/virstring.h
+++ b/src/util/virstring.h
@@ -93,7 +93,7 @@ int virStrdup(char **dest, const char *src, bool report, int domcode,
               const char *filename, const char *funcname, size_t linenr)
     ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
 
-int virStrndup(char **dest, const char *src, size_t n, bool report, int domcode,
+int virStrndup(char **dest, const char *src, ssize_t n, bool report, int domcode,
                const char *filename, const char *funcname, size_t linenr)
     ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
 
@@ -132,7 +132,9 @@ int virStrndup(char **dest, const char *src, size_t n, bool report, int domcode,
  * @n: the maximum number of bytes to copy
  *
  * Duplicate @src string and store it into @dst. If @src is longer than @n,
- * only @n bytes are copied and terminating null byte '\0' is added.
+ * only @n bytes are copied and terminating null byte '\0' is added. If @n
+ * is a negative number, then the whole @src string is copied. That is
+ * VIR_STRDUP(dst, src) and VIR_STRNDUP(dst, src, -1) are equal.
  *
  * This macro is safe to use on arguments with side effects.
  *
@@ -150,7 +152,10 @@ int virStrndup(char **dest, const char *src, size_t n, bool report, int domcode,
  * @n: the maximum number of bytes to copy
  *
  * Duplicate @src string and store it into @dst. If @src is longer than @n,
- * only @n bytes are copied and terminating null byte '\0' is added.
+ * only @n bytes are copied and terminating null byte '\0' is added. If @n
+ * is a negative number, then the whole @src string is copied. That is
+ * VIR_STRDUP_QUIET(dst, src) and VIR_STRNDUP_QUIET(dst, src, -1) are
+ * equal.
  *
  * This macro is safe to use on arguments with side effects.
  *
diff --git a/tests/virstringtest.c b/tests/virstringtest.c
index da06c0f..3d0b55b 100644
--- a/tests/virstringtest.c
+++ b/tests/virstringtest.c
@@ -196,6 +196,39 @@ cleanup:
     return ret;
 }
 
+static int
+testStrndupNegative(const void *opaque ATTRIBUTE_UNUSED)
+{
+    int ret = -1;
+    char *dst;
+    const char *src = "Hello world";
+    int value;
+
+    if ((value = VIR_STRNDUP(dst, src, 5)) != 1) {
+        fprintf(stderr, "unexpected virStrndup result %d, expected 1\n", value);
+        goto cleanup;
+    }
+
+    if (STRNEQ_NULLABLE(dst, "Hello")) {
+        fprintf(stderr, "unexpected content '%s'", dst);
+        goto cleanup;
+    }
+
+    if ((value = VIR_STRNDUP(dst, src, -1)) != 1) {
+        fprintf(stderr, "unexpected virStrndup result %d, expected 1\n", value);
+        goto cleanup;
+    }
+
+    if (STRNEQ_NULLABLE(dst, src)) {
+        fprintf(stderr, "unexpected content '%s'", dst);
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    VIR_FREE(dst);
+    return ret;
+}
 
 static int
 mymain(void)
@@ -245,6 +278,9 @@ mymain(void)
     if (virtTestRun("strdup", 1, testStrdup, NULL) < 0)
         ret = -1;
 
+    if (virtTestRun("strdup", 1, testStrndupNegative, NULL) < 0)
+        ret = -1;
+
     return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
 
-- 
1.8.2.1




More information about the libvir-list mailing list