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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list