[libvirt] [PATCH v2 02/37] virstring: Introduce VIR_STRUP and VIR_STRNDUP

Michal Privoznik mprivozn at redhat.com
Mon Apr 29 13:50:24 UTC 2013


The code adaptation is not done right now, but in subsequent patches.
Hence I am not implementing syntax-check rule as it would break
compilation. Developers are strongly advised to use these new macros.
They are similar to VIR_ALLOC() logic: VIR_STRDUP(dst, src) returns zero
on success, -1 otherwise. In case you don't want to report OOM error,
use _QUIET variant of a macro.
---
 HACKING                  | 11 +++++++
 docs/hacking.html.in     | 14 +++++++++
 src/libvirt_private.syms |  2 ++
 src/util/virstring.c     | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virstring.h     | 20 +++++++++++++
 5 files changed, 121 insertions(+)

diff --git a/HACKING b/HACKING
index e8bebd4..842f476 100644
--- a/HACKING
+++ b/HACKING
@@ -719,6 +719,17 @@ sizeof(dest) returns something meaningful). Note that this is a macro, so
 arguments could be evaluated more than once. This is equivalent to
 virStrncpy(dest, src, strlen(src), sizeof(dest)).
 
+  VIR_STRDUP(char *dst, const char *src);
+  VIR_STRNDUP(char *dst, const char *src, size_t n);
+
+You should avoid using strdup or strndup directly as the does not report
+out-of-memory error. Use VIR_STRDUP() or VIR_STRNDUP macros instead. Note,
+that these two behave in similar way to VIR_ALLOC: on success zero is
+returned, otherwise caller is left with negative one. In very specific case,
+when you don't want to report the out-of-memory error, you can use
+VIR_STRDUP_QUIET or VIR_STRNDUP_QUIET, but such usage is very rare and usually
+considered a flaw.
+
 
 Variable length string buffer
 =============================
diff --git a/docs/hacking.html.in b/docs/hacking.html.in
index 99933d1..1263607 100644
--- a/docs/hacking.html.in
+++ b/docs/hacking.html.in
@@ -853,6 +853,20 @@
       virStrncpy(dest, src, strlen(src), sizeof(dest)).
     </p>
 
+<pre>
+  VIR_STRDUP(char *dst, const char *src);
+  VIR_STRNDUP(char *dst, const char *src, size_t n);
+</pre>
+    <p>
+      You should avoid using strdup or strndup directly as the does not report
+      out-of-memory error.  Use VIR_STRDUP() or VIR_STRNDUP macros instead.
+      Note, that these two behave in similar way to VIR_ALLOC: on success zero
+      is returned, otherwise caller is left with negative one. In very specific
+      case, when you don't want to report the out-of-memory error, you can use
+      VIR_STRDUP_QUIET or VIR_STRNDUP_QUIET, but such usage is very rare and
+      usually considered a flaw.
+    </p>
+
     <h2><a name="strbuf">Variable length string buffer</a></h2>
 
     <p>
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 98660dc..d4cb4a3 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1751,11 +1751,13 @@ virSkipSpaces;
 virSkipSpacesAndBackslash;
 virSkipSpacesBackwards;
 virStrcpy;
+virStrdup;
 virStringArrayHasString;
 virStringFreeList;
 virStringJoin;
 virStringSplit;
 virStrncpy;
+virStrndup;
 virStrToDouble;
 virStrToLong_i;
 virStrToLong_l;
diff --git a/src/util/virstring.c b/src/util/virstring.c
index 9b4cb01..4a55873 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -515,3 +515,77 @@ virArgvToString(const char *const *argv)
 
     return ret;
 }
+
+/**
+ * virStrdup:
+ * @dest: where to store duplicated string
+ * @src: the source string to duplicate
+ * @report: whether to report OOM error, if there's a one
+ * @domcode: error domain code
+ * @filename: caller's filename
+ * @funcname: caller's funcname
+ * @linenr: caller's line number
+ *
+ * Wrapper over strdup, which reports OOM error if told so,
+ * in which case callers wants to pass @domcode, @filename,
+ * @funcname and @linenr which should represent location in
+ * caller's body where virStrdup is called from. Consider
+ * using VIR_STRDUP which sets these automatically.
+ *
+ * Returns: 0 on success, -1 othervise.
+ */
+int
+virStrdup(char **dest,
+          const char *src,
+          bool report,
+          int domcode,
+          const char *filename,
+          const char *funcname,
+          size_t linenr)
+{
+    if (!(*dest = strdup(src))) {
+        if (report)
+            virReportOOMErrorFull(domcode, filename, funcname, linenr);
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * virStrndup:
+ * @dest: where to store duplicated string
+ * @src: the source string to duplicate
+ * @n: how many bytes to copy
+ * @report: whether to report OOM error, if there's a one
+ * @domcode: error domain code
+ * @filename: caller's filename
+ * @funcname: caller's funcname
+ * @linenr: caller's line number
+ *
+ * Wrapper over strndup, which reports OOM error if told so,
+ * in which case callers wants to pass @domcode, @filename,
+ * @funcname and @linenr which should represent location in
+ * caller's body where virStrdup is called from. Consider
+ * using VIR_STRNDUP which sets these automatically.
+ *
+ * Returns: 0 on success, -1 othervise.
+ */
+int
+virStrndup(char **dest,
+           const char *src,
+           size_t n,
+           bool report,
+           int domcode,
+           const char *filename,
+           const char *funcname,
+           size_t linenr)
+{
+    if (!(*dest = strndup(src, n))) {
+        if (report)
+            virReportOOMErrorFull(domcode, filename, funcname, linenr);
+        return -1;
+    }
+
+   return 0;
+}
diff --git a/src/util/virstring.h b/src/util/virstring.h
index 457caa2..620efba 100644
--- a/src/util/virstring.h
+++ b/src/util/virstring.h
@@ -87,4 +87,24 @@ char *virStrncpy(char *dest, const char *src, size_t n, size_t destbytes)
 char *virStrcpy(char *dest, const char *src, size_t destbytes)
     ATTRIBUTE_RETURN_CHECK;
 # define virStrcpyStatic(dest, src) virStrcpy((dest), (src), sizeof(dest))
+
+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) ATTRIBUTE_NONNULL(2);
+
+/* XXX Don't report OOM error for now, unless all code is adapted. */
+# define VIR_STRDUP(dst, src) virStrdup(&(dst), src, false, VIR_FROM_THIS, \
+                                        __FILE__, __FUNCTION__, __LINE__)
+# define VIR_STRDUP_QUIET(dst, src) virStrdup(&(dst), src, false, 0, NULL, NULL, 0)
+int virStrndup(char **dest, const char *src, size_t n, bool report, int domcode,
+               const char *filename, const char *funcname, size_t linenr)
+    ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+/* XXX Don't report OOM error for now, unless all code is adapted. */
+# define VIR_STRNDUP(dst, src, n) virStrndup(&(dst), src, n, false,   \
+                                             VIR_FROM_THIS, __FILE__, \
+                                             __FUNCTION__, __LINE__)
+
+# define VIR_STRNDUP_QUIET(dst, src, n) virStrndup(&(dst), src, n, false, \
+                                                   0, NULL, NULL, 0)
 #endif /* __VIR_STRING_H__ */
-- 
1.8.1.5




More information about the libvir-list mailing list