diff --git a/include/string.h b/include/string.h --- a/include/string.h +++ b/include/string.h @@ -66,6 +66,9 @@ void *memmem(const void *, size_t, const void *, size_t) __pure; #endif void *memmove(void *, const void *, size_t); +#if __BSD_VISIBLE +void *mempcpy(void * __restrict, const void * __restrict, size_t); +#endif void *memset(void *, int, size_t); #if __POSIX_VISIBLE >= 200809 char *stpcpy(char * __restrict, const char * __restrict); diff --git a/include/wchar.h b/include/wchar.h --- a/include/wchar.h +++ b/include/wchar.h @@ -172,6 +172,9 @@ int wmemcmp(const wchar_t *, const wchar_t *, size_t) __pure; wchar_t *wmemcpy(wchar_t * __restrict, const wchar_t * __restrict, size_t); wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t); +#if __BSD_VISIBLE +wchar_t *wmempcpy(wchar_t * __restrict, const wchar_t * __restrict, size_t); +#endif wchar_t *wmemset(wchar_t *, wchar_t, size_t); int wprintf(const wchar_t * __restrict, ...); int wscanf(const wchar_t * __restrict, ...); diff --git a/lib/libc/Versions.def b/lib/libc/Versions.def --- a/lib/libc/Versions.def +++ b/lib/libc/Versions.def @@ -35,6 +35,9 @@ FBSD_1.6 { } FBSD_1.5; +FBSD_1.7 { +} FBSD_1.6; + # This is our private namespace. Any global interfaces that are # strictly for use only by other FreeBSD applications and libraries # are listed here. We use a separate namespace so we can write @@ -42,4 +45,4 @@ # # Please do NOT increment the version of this namespace. FBSDprivate_1.0 { -} FBSD_1.6; +} FBSD_1.7; diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc --- a/lib/libc/string/Makefile.inc +++ b/lib/libc/string/Makefile.inc @@ -10,7 +10,7 @@ MISRCS+=bcmp.c bcopy.c bzero.c explicit_bzero.c \ ffs.c ffsl.c ffsll.c fls.c flsl.c flsll.c \ memccpy.c memchr.c memrchr.c memcmp.c \ - memcpy.c memmem.c memmove.c memset.c memset_s.c \ + memcpy.c memmem.c memmove.c mempcpy.c memset.c memset_s.c \ stpcpy.c stpncpy.c strcasecmp.c \ strcat.c strcasestr.c strchr.c strchrnul.c strcmp.c strcoll.c strcpy.c\ strcspn.c strdup.c strerror.c strlcat.c strlcpy.c strlen.c strmode.c \ @@ -25,7 +25,7 @@ wcsncpy.c wcsnlen.c wcspbrk.c \ wcsrchr.c wcsspn.c wcsstr.c wcstok.c wcswidth.c wcsxfrm.c wmemchr.c \ wmemcmp.c \ - wmemcpy.c wmemmove.c wmemset.c + wmemcpy.c wmemmove.c wmempcpy.c wmemset.c SYM_MAPS+= ${LIBC_SRCTOP}/string/Symbol.map @@ -50,6 +50,7 @@ ffs.3 flsll.3 MLINKS+=index.3 rindex.3 MLINKS+=memchr.3 memrchr.3 +MLINKS+=memcpy.3 mempcpy.3 MLINKS+=memset.3 memset_s.3 MLINKS+=strcasecmp.3 strncasecmp.3 \ strcasecmp.3 strcasecmp_l.3 \ @@ -101,4 +102,5 @@ wmemchr.3 wmemcmp.3 \ wmemchr.3 wmemcpy.3 \ wmemchr.3 wmemmove.3 \ + wmemchr.3 wmempcpy.3 \ wmemchr.3 wmemset.3 diff --git a/lib/libc/string/Symbol.map b/lib/libc/string/Symbol.map --- a/lib/libc/string/Symbol.map +++ b/lib/libc/string/Symbol.map @@ -114,6 +114,11 @@ strerror_l; }; +FBSD_1.7 { + mempcpy; + wmempcpy; +}; + FBSDprivate_1.0 { __strtok_r; }; diff --git a/lib/libc/string/memcpy.3 b/lib/libc/string/memcpy.3 --- a/lib/libc/string/memcpy.3 +++ b/lib/libc/string/memcpy.3 @@ -32,7 +32,7 @@ .\" @(#)memcpy.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd June 4, 1993 +.Dd July 14, 2021 .Dt MEMCPY 3 .Os .Sh NAME @@ -44,11 +44,15 @@ .In string.h .Ft void * .Fn memcpy "void *dst" "const void *src" "size_t len" +.Ft void * +.Fn mempcpy "void *dst" "const void *src" "size_t len" .Sh DESCRIPTION The .Fn memcpy -function -copies +and +.Fn mempcpy +functions +copy .Fa len bytes from string .Fa src @@ -65,12 +69,17 @@ function returns the original value of .Fa dst . +.Pp +The +.Fn mempcpy +function returns a pointer to the byte after the last written byte. .Sh SEE ALSO .Xr bcopy 3 , .Xr memccpy 3 , .Xr memmove 3 , .Xr strcpy 3 , .Xr wmemcpy 3 +.Xr wmempcpy 3 .Sh STANDARDS The .Fn memcpy @@ -80,7 +89,9 @@ .Sh BUGS In this implementation .Fn memcpy -is implemented using +and +.Fn mempcpy +are implemented using .Xr bcopy 3 , and therefore the strings may overlap. On other systems, copying overlapping strings may produce surprises. diff --git a/lib/libc/string/mempcpy.c b/lib/libc/string/mempcpy.c new file mode 100644 --- /dev/null +++ b/lib/libc/string/mempcpy.c @@ -0,0 +1,41 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2021 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +void * +mempcpy(void *dst, const void *src, size_t len) +{ + return ((char *)memcpy(dst, src, len) + len); +} diff --git a/lib/libc/string/wmemchr.3 b/lib/libc/string/wmemchr.3 --- a/lib/libc/string/wmemchr.3 +++ b/lib/libc/string/wmemchr.3 @@ -35,7 +35,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 4, 2009 +.Dd July 14, 2021 .Dt WMEMCHR 3 .Os .Sh NAME @@ -43,6 +43,7 @@ .Nm wmemcmp , .Nm wmemcpy , .Nm wmemmove , +.Nm wmempcpy , .Nm wmemset , .Nm wcpcpy , .Nm wcpncpy , @@ -79,6 +80,8 @@ .Ft wchar_t * .Fn wmemmove "wchar_t *s1" "const wchar_t *s2" "size_t n" .Ft wchar_t * +.Fn wmempcpy "wchar_t * restrict s1" "const wchar_t * restrict s2" "size_t n" +.Ft wchar_t * .Fn wmemset "wchar_t *s" "wchar_t c" "size_t n" .Ft wchar_t * .Fn wcpcpy "wchar_t *s1" "wchar_t *s2" @@ -168,7 +171,8 @@ which conform to .St -p1003.1-2008 ; and -.Fn wcslcat -and +.Fn wcslcat , .Fn wcslcpy , +and +.Fn wmempcpy , which are extensions. diff --git a/lib/libc/string/wmempcpy.c b/lib/libc/string/wmempcpy.c new file mode 100644 --- /dev/null +++ b/lib/libc/string/wmempcpy.c @@ -0,0 +1,42 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2021 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +wchar_t * +wmempcpy(wchar_t *dst, const wchar_t *src, size_t len) +{ + return (wmemcpy(dst, src, len) + len); +}