* 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,
{
if (!src)
return 0;
+ if (n < 0)
+ n = strlen(src);
if (!(*dest = strndup(src, n))) {
if (report)
virReportOOMErrorFull(domcode, filename, funcname, linenr);
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);
* @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.
*
* @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.
*
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;
+ }
+
+ VIR_FREE(dst);
+ 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)
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;
}