diff --git a/include/string.h b/include/string.h index efc8aecec081..fb373c88e39d 100644 --- a/include/string.h +++ b/include/string.h @@ -61,6 +61,7 @@ void *memccpy(void * __restrict, const void * __restrict, int, size_t); void *memchr(const void *, int, size_t) __pure; int memcmp(const void *, const void *, size_t) __pure; void *memcpy(void * __restrict, const void * __restrict, size_t); +void *memmem(const void *, size_t, const void *, size_t); void *memmove(void *, const void *, size_t); void *memset(void *, int, size_t); #if __BSD_VISIBLE diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc index e6d8ea5eae75..77fe8e0da6be 100644 --- a/lib/libc/string/Makefile.inc +++ b/lib/libc/string/Makefile.inc @@ -8,10 +8,10 @@ CFLAGS+= -I${.CURDIR}/locale # machine-independent string sources MISRCS+=bcmp.c bcopy.c bzero.c ffs.c ffsl.c fls.c flsl.c index.c memccpy.c \ memchr.c memcmp.c \ - memcpy.c memmove.c memset.c rindex.c stpcpy.c strcasecmp.c strcat.c \ - strchr.c strcmp.c strcoll.c strcpy.c strcspn.c strdup.c strerror.c \ - strlcat.c strlcpy.c strlen.c strmode.c strncat.c strncmp.c strncpy.c \ - strcasestr.c strnstr.c \ + memcpy.c memmem.c memmove.c memset.c rindex.c stpcpy.c strcasecmp.c \ + strcat.c strchr.c strcmp.c strcoll.c strcpy.c strcspn.c strdup.c \ + strerror.c strlcat.c strlcpy.c strlen.c strmode.c strncat.c strncmp.c \ + strncpy.c strcasestr.c strnstr.c \ strpbrk.c strrchr.c strsep.c strsignal.c strspn.c strstr.c strtok.c \ strxfrm.c swab.c wcscat.c wcschr.c wcscmp.c wcscoll.c wcscpy.c \ wcscspn.c wcsdup.c \ @@ -27,7 +27,7 @@ MISRCS+=bcmp.c bcopy.c bzero.c ffs.c ffsl.c fls.c flsl.c index.c memccpy.c \ .endif MAN+= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \ - memcmp.3 memcpy.3 memmove.3 memset.3 strcasecmp.3 strcat.3 \ + memcmp.3 memcpy.3 memmem.3 memmove.3 memset.3 strcasecmp.3 strcat.3 \ strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strdup.3 strerror.3 \ string.3 strlcpy.3 strlen.3 strmode.3 strpbrk.3 strsep.3 \ strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 wcscoll.3 wcstok.3 \ diff --git a/lib/libc/string/memchr.3 b/lib/libc/string/memchr.3 index 87215534b828..1c06785d8e4d 100644 --- a/lib/libc/string/memchr.3 +++ b/lib/libc/string/memchr.3 @@ -66,6 +66,7 @@ or NULL if no such byte exists within .Fa len bytes. .Sh SEE ALSO +.Xr memmem 3 , .Xr strchr 3 , .Xr strcspn 3 , .Xr strpbrk 3 , diff --git a/lib/libc/string/memmem.3 b/lib/libc/string/memmem.3 new file mode 100644 index 000000000000..678ae3d07f0c --- /dev/null +++ b/lib/libc/string/memmem.3 @@ -0,0 +1,84 @@ +.\" Copyright (c) 2005 Pascal Gloor +.\" +.\" 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. +.\" 3. The name of the author may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" 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. +.\" +\" $FreeBSD$ +.\" +.Dd August 24, 2005 +.Dt MEMMEM 3 +.Os +.Sh NAME +.Nm memmem +.Nd locate a byte substring in a byte string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In string.h +.Ft void * +.Fn memmem "const char *big" "size_t big_len" \ +"const char *little" "size_t little_len" +.Sh DESCRIPTION +The +.Fn memmem +function +locates the first occurrence of the byte string +.Fa little +in the byte string +.Fa big . +.Sh RETURN VALUES +If +.Fa big_len +is smaller than +.Fa little_len , +if +.Fa little_len +is 0, if +.Fa big_len +is 0 or if +.Fa little +occurs nowhere in +.Fa big , +.Dv NULL +is returned; +otherwise a pointer to the first character of the first occurrence of +.Fa little +is returned. +.Sh SEE ALSO +.Xr memchr 3 , +.Xr strchr 3 , +.Xr strstr 3 +.Sh CONFORMING TO +.Fn memmem +is a GNU extension. +.Sh HISTORY +The +.Fn memmem +function first appeared in +.Fx 6.0 . +.Sh AUTHOR +Pascal Gloor +.Sh BUGS +This function was broken in Linux libc up to and including version 5.0.9 +and in GNU libc prior to version 2.1. diff --git a/lib/libc/string/memmem.c b/lib/libc/string/memmem.c new file mode 100644 index 000000000000..0ac0a6dfc80e --- /dev/null +++ b/lib/libc/string/memmem.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2005 Pascal Gloor + * + * 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. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 + +/* + * Find the first occurrence of the byte string s in byte string l. + */ + +void * +memmem(l, l_len, s, s_len) + const void *l; size_t l_len; + const void *s; size_t s_len; +{ + register char *cur, *last; + const char *cl = (const char *)l; + const char *cs = (const char *)s; + + /* we need something to compare */ + if (l_len == 0 || s_len == 0) + return NULL; + + /* "s" must be smaller or equal to "l" */ + if (l_len < s_len) + return NULL; + + /* special case where s_len == 1 */ + if (s_len == 1) + return memchr(l, (int)*cs, l_len); + + /* the last position where its possible to find "s" in "l" */ + last = (char *)cl + l_len - s_len; + + for (cur = (char *)cl; cur <= last; cur++) + if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) + return cur; + + return NULL; +} diff --git a/lib/libc/string/strchr.3 b/lib/libc/string/strchr.3 index 2936be77fd5a..5d801ef7f66e 100644 --- a/lib/libc/string/strchr.3 +++ b/lib/libc/string/strchr.3 @@ -83,6 +83,7 @@ return a pointer to the located character, or if the character does not appear in the string. .Sh SEE ALSO .Xr memchr 3 , +.Xr memmem 3 , .Xr strcspn 3 , .Xr strpbrk 3 , .Xr strsep 3 , diff --git a/lib/libc/string/strstr.3 b/lib/libc/string/strstr.3 index 16c6db20fa75..a2136c80a488 100644 --- a/lib/libc/string/strstr.3 +++ b/lib/libc/string/strstr.3 @@ -132,6 +132,7 @@ ptr = strnstr(largestring, smallstring, 4); .Ed .Sh SEE ALSO .Xr memchr 3 , +.Xr memmem 3 , .Xr strchr 3 , .Xr strcspn 3 , .Xr strpbrk 3 ,