[PATCH v3 01/15] lib: Add memdup()

Heinrich Schuchardt xypron.glpk at gmx.de
Sun Aug 1 23:25:17 CEST 2021



On 8/1/21 11:00 PM, Simon Glass wrote:
> Add a function to duplicate a memory region, a little like strdup().
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> (no changes since v2)
>
> Changes in v2:
> - Add a patch to introduce a memdup() function
>
>   include/linux/string.h | 13 +++++++++++++
>   lib/string.c           | 13 +++++++++++++
>   test/lib/string.c      | 32 ++++++++++++++++++++++++++++++++
>   3 files changed, 58 insertions(+)
>
> diff --git a/include/linux/string.h b/include/linux/string.h
> index dd255f21633..3169c93796e 100644
> --- a/include/linux/string.h
> +++ b/include/linux/string.h
> @@ -129,6 +129,19 @@ extern void * memchr(const void *,int,__kernel_size_t);
>   void *memchr_inv(const void *, int, size_t);
>   #endif
>
> +/**
> + * memdup() - allocate a buffer and copy in the contents

This partially duplicates realloc(). The only difference is that
realloc() frees the old buffer. But it seems rEALLOc() has too much
logic to easily join the two functions.

Reviewed-by: Heinrich Schuchardt <xypron.glpk at gmx.de>

> + *
> + * Note that this returns a valid pointer even if @len is 0
> + *
> + * @src: data to copy in
> + * @len: number of bytes to copy
> + * @return allocated buffer with the copied contents, or NULL if not enough
> + *	memory is available
> + *
> + */
> +char *memdup(const void *src, size_t len);
> +
>   unsigned long ustrtoul(const char *cp, char **endp, unsigned int base);
>   unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base);
>
> diff --git a/lib/string.c b/lib/string.c
> index ba176fb08f7..78bd65c4136 100644
> --- a/lib/string.c
> +++ b/lib/string.c
> @@ -659,6 +659,19 @@ void * memscan(void * addr, int c, size_t size)
>   }
>   #endif
>
> +char *memdup(const void *src, size_t len)
> +{
> +	char *p;
> +
> +	p = malloc(len);
> +	if (!p)
> +		return NULL;
> +
> +	memcpy(p, src, len);
> +
> +	return p;
> +}
> +
>   #ifndef __HAVE_ARCH_STRSTR
>   /**
>    * strstr - Find the first substring in a %NUL terminated string
> diff --git a/test/lib/string.c b/test/lib/string.c
> index 64234bef36c..5dcf4d6db00 100644
> --- a/test/lib/string.c
> +++ b/test/lib/string.c
> @@ -23,6 +23,8 @@
>   /* Allow for copying up to 32 bytes */
>   #define BUFLEN (SWEEP + 33)
>
> +#define TEST_STR	"hello"
> +
>   /**
>    * init_buffer() - initialize buffer
>    *
> @@ -193,3 +195,33 @@ static int lib_memmove(struct unit_test_state *uts)
>   }
>
>   LIB_TEST(lib_memmove, 0);
> +
> +/** lib_memdup() - unit test for memdup() */
> +static int lib_memdup(struct unit_test_state *uts)
> +{
> +	char buf[BUFLEN];
> +	size_t len;
> +	char *p, *q;
> +
> +	/* Zero size should do nothing */
> +	p = memdup(NULL, 0);
> +	ut_assertnonnull(p);
> +	free(p);
> +
> +	p = memdup(buf, 0);
> +	ut_assertnonnull(p);
> +	free(p);
> +
> +	strcpy(buf, TEST_STR);
> +	len = sizeof(TEST_STR);
> +	p = memdup(buf, len);
> +	ut_asserteq_mem(p, buf, len);
> +
> +	q = memdup(p, len);
> +	ut_asserteq_mem(q, buf, len);
> +	free(q);
> +	free(p);
> +
> +	return 0;
> +}
> +LIB_TEST(lib_memdup, 0);
>


More information about the U-Boot mailing list