fa.openbsd.tech
[Top] [All Lists]

memdup(3)

Subject: memdup(3)
From: Alexey Dobriyan <adobriyan@xxxxxxxxx>
Date: Mon, 14 Jul 2008 12:54:40 UTC
Newsgroups: fa.openbsd.tech

memdup(3) has strdup(3) semantics but without strings.

Canonical code for duplicating buffer looks like:

        rpl = malloc(src, len);
        if (!rpl)
                ...
        memcpy(rpl, src, len);

Mistakes happen and two lengths in snippet above will be different.
To prevent this memdup(3) was created:

        rpl = memdup(src, len);
        if (!rpl)
                ...
        ...

Index: memdup.c
===================================================================
RCS file: memdup.c
diff -N memdup.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ memdup.c    14 Jul 2008 12:27:18 -0000
@@ -0,0 +1,31 @@
+/*
+ * $OpenBSD$
+ *
+ * Copyright (c) 2008 Alexey Dobriyan <adobriyan@xxxxxxxxx>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
+void *
+memdup(const void *src, size_t len)
+{
+       void *dst;
+
+       dst = malloc(len);
+       if (dst)
+               memcpy(dst, src, len);
+       return dst;
+}
Index: memdup.3
===================================================================
RCS file: memdup.3
diff -N memdup.3
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ memdup.3    14 Jul 2008 12:27:18 -0000
@@ -0,0 +1,66 @@
+.\" $OpenBSD$
+./"
+./"Copyright (c) 2008 Alexey Dobriyan <adobriyan@xxxxxxxxx>
+./"
+./"Permission to use, copy, modify, and distribute this software for any
+./"purpose with or without fee is hereby granted, provided that the above
+./"copyright notice and this permission notice appear in all copies.
+./"
+./"THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+./"WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+./"MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+./"ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+./"WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+./"ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+./"OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+./"
+.Dd $Mdocdate: Jul 14 2008 $
+.Dt STRDUP 3
+.Os
+.Sh NAME
+.Nm memdup
+.Nd save a copy of a buffer
+.Sh SYNOPSIS
+.Fd #include <string.h>
+.Ft void *
+.Fn memdup "const void *src, size_t len"
+.Sh DESCRIPTION
+The
+.Fn memdup
+function allocates sufficient memory for a copy of the buffer
+.Fa src ,
+does the copy, and returns a pointer to it.
+The pointer may subsequently be used as an argument to the function
+.Xr free 3 .
+.Pp
+If insufficient memory is available,
+.Dv NULL
+is returned.
+.Sh EXAMPLES
+The following will point
+.Va p
+to an allocated area of memory containing the replica of buffer
+.Va src
+which has length
+.Va len :
+.Bd -literal -offset indent
+void *p;
+
+p = memdup(src, len);
+if (!p) {
+       fprintf(stderr, "Out of memory.\en");
+       exit(1);
+}
+.Ed
+.Sh ERRORS
+The
+.Fn memdup
+function may fail and set the external variable
+.Va errno
+for any of the errors specified for the library function
+.Xr malloc 3 .
+.Sh SEE ALSO
+.Xr free 3 ,
+.Xr malloc 3 ,
+.Xr memcpy 3 ,
+.Xr strdup 3
Index: Makefile.inc
===================================================================
RCS file: /cvs/src/lib/libc/string/Makefile.inc,v
retrieving revision 1.20
diff -u -r1.20 Makefile.inc
--- Makefile.inc        25 Oct 2007 22:41:02 -0000      1.20
+++ Makefile.inc        14 Jul 2008 12:31:27 -0000
@@ -3,7 +3,8 @@
 # string sources
 .PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/string ${LIBCSRCDIR}/string
 
-SRCS+= bm.c memccpy.c memrchr.c strcasecmp.c strcasestr.c strcoll.c strdup.c \
+SRCS+= bm.c memccpy.c memdup.c memrchr.c strcasecmp.c strcasestr.c strcoll.c \
+       strdup.c \
        strerror.c strerror_r.c strlcat.c strmode.c strsignal.c strtok.c \
        strxfrm.c \
        wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \
@@ -139,7 +140,7 @@
                ${LIBCSRCDIR}/string/rindex.c
 
 MAN+=  bm.3 bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 memccpy.3 memchr.3 \
-       memcmp.3 memcpy.3 memmove.3 memset.3 strcasecmp.3 strcat.3 \
+       memcmp.3 memcpy.3 memdup.3 memmove.3 memset.3 strcasecmp.3 strcat.3 \
        strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strerror.3 \
        string.3 strlen.3 strmode.3 strdup.3 strpbrk.3 strrchr.3 strsep.3 \
        strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 strlcpy.3 \


<Prev in Thread] Current Thread [Next in Thread>