]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virstring: Introduce VIR_STRDUP and VIR_STRNDUP
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 3 Apr 2013 12:51:20 +0000 (14:51 +0200)
committerGuido Günther <agx@sigxcpu.org>
Sat, 11 Jan 2014 12:26:28 +0000 (13:26 +0100)
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 the _QUIET variant of a macro.

Conflicts:
src/libvirt_private.syms
src/util/virstring.h

(cherry picked from commit c3abb5c45988a0d7583f059974513722d82e2c2b)

HACKING
docs/hacking.html.in
src/libvirt_private.syms
src/util/virstring.c
src/util/virstring.h

diff --git a/HACKING b/HACKING
index 69ea96b29d1763f68feb8682cf555e34fa15e5a2..5b5c34be9be2f7ed409d51f994d749688bfe4d54 100644 (file)
--- a/HACKING
+++ b/HACKING
@@ -535,6 +535,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 they do not report
+out-of-memory error. Use VIR_STRDUP or VIR_STRNDUP macros instead. Note, that
+these two behave similar to VIR_ALLOC: on success zero is returned, otherwise
+the result is -1 and dst is guaranteed to be NULL. In very specific cases,
+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
 =============================
index 89f9980f45a1cc16f2e605b09b2767b565f4cb11..198afe7617339e822d6c721de4266842e6e0fd7e 100644 (file)
       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 they do not report
+      out-of-memory error. Use VIR_STRDUP or VIR_STRNDUP macros instead.  Note,
+      that these two behave similar to VIR_ALLOC: on success zero is returned,
+      otherwise the result is -1 and dst is guaranteed to be NULL. In very
+      specific cases, 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>
index f35fd6333beb0307d5a9c40480ae8870b1e712bc..21b593a8a1d5b0a615c65d8954e032fceb7f97dc 100644 (file)
@@ -1495,9 +1495,11 @@ virStrerror;
 
 
 # virstring.h
+virStrdup;
 virStringSplit;
 virStringJoin;
 virStringFreeList;
+virStrndup;
 
 
 # virtime.h
index 92289eb93c3fb20f0a25dce2dc10e672fe9e4230..21142b4a838399919f5ee8e03d5e163ebb83f8d4 100644 (file)
@@ -177,3 +177,77 @@ size_t virStringListLength(char **strings)
 
     return i;
 }
+
+/**
+ * virStrdup:
+ * @dest: where to store duplicated string
+ * @src: the source string to duplicate
+ * @report: whether to report OOM error, if there is 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 otherwise.
+ */
+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 is 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 virStrndup is called from. Consider
+ * using VIR_STRNDUP which sets these automatically.
+ *
+ * Returns: 0 on success, -1 otherwise.
+ */
+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;
+}
index d68ed2f68972e156c38120877cdb3b3e2b71c1e1..cd5ccda9f97aeb6377dca174809df726ac042093 100644 (file)
@@ -37,4 +37,64 @@ void virStringFreeList(char **strings);
 
 size_t virStringListLength(char **strings);
 
+/* Don't call these directly - use the macros below */
+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);
+
+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);
+
+/**
+ * VIR_STRDUP:
+ * @dst: variable to hold result (char*, not char**)
+ * @src: string to duplicate
+ *
+ * Duplicate @src string and store it into @dst.
+ *
+ * Returns -1 on failure (with OOM error reported), 0 on success
+ */
+# define VIR_STRDUP(dst, src) virStrdup(&(dst), src, true, VIR_FROM_THIS, \
+                                        __FILE__, __FUNCTION__, __LINE__)
+
+/**
+ * VIR_STRDUP_QUIET:
+ * @dst: variable to hold result (char*, not char**)
+ * @src: string to duplicate
+ *
+ * Duplicate @src string and store it into @dst.
+ *
+ * Returns -1 on failure, 0 on success
+ */
+# define VIR_STRDUP_QUIET(dst, src) virStrdup(&(dst), src, false, 0, NULL, NULL, 0)
+
+/**
+ * VIR_STRNDUP:
+ * @dst: variable to hold result (char*, not char**)
+ * @src: string to duplicate
+ * @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.
+ *
+ * Returns -1 on failure (with OOM error reported), 0 on success
+ */
+# define VIR_STRNDUP(dst, src, n) virStrndup(&(dst), src, n, true,    \
+                                             VIR_FROM_THIS, __FILE__, \
+                                             __FUNCTION__, __LINE__)
+
+/**
+ * VIR_STRNDUP_QUIET:
+ * @dst: variable to hold result (char*, not char**)
+ * @src: string to duplicate
+ * @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.
+ *
+ * Returns -1 on failure, 0 on success
+ */
+# define VIR_STRNDUP_QUIET(dst, src, n) virStrndup(&(dst), src, n, false, \
+                                                   0, NULL, NULL, 0)
 #endif /* __VIR_STRING_H__ */