add strnstr(9) string search within character limit
authorjsg <jsg@openbsd.org>
Thu, 21 Dec 2023 02:57:14 +0000 (02:57 +0000)
committerjsg <jsg@openbsd.org>
Thu, 21 Dec 2023 02:57:14 +0000 (02:57 +0000)
From Mike Barcroft in FreeBSD.  Added to FreeBSD in 2001, Linux in 2010.
Used in amdgpu.

ok deraadt@

share/man/man9/Makefile
share/man/man9/strnstr.9 [new file with mode: 0644]
sys/conf/files
sys/lib/libkern/libkern.h
sys/lib/libkern/strnstr.c [new file with mode: 0644]

index f675082..c990a8a 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.308 2022/11/05 19:29:45 cheloha Exp $
+#      $OpenBSD: Makefile,v 1.309 2023/12/21 02:57:14 jsg Exp $
 #      $NetBSD: Makefile,v 1.4 1996/01/09 03:23:01 thorpej Exp $
 
 #      Makefile for section 9 (kernel function and variable) manual pages.
@@ -39,7 +39,8 @@ MAN=  aml_evalnode.9 atomic_add_int.9 atomic_cas_uint.9 \
        sensor_attach.9 sigio_init.9 \
        SMR_LIST_INIT.9 SMR_PTR_GET.9 smr_call.9 \
        spl.9 srp_enter.9 srpl_rc_init.9 startuphook_establish.9 socreate.9 \
-       sosplice.9 stoeplitz_to_key.9 strcmp.9 style.9 syscall.9 sysctl_int.9 \
+       sosplice.9 stoeplitz_to_key.9 strcmp.9 strnstr.9 \
+       style.9 syscall.9 sysctl_int.9 \
        task_add.9 tc_init.9 tfind.9 thread_fork.9 \
        timeout.9 tsleep.9 tvtohz.9 \
        uiomove.9 \
diff --git a/share/man/man9/strnstr.9 b/share/man/man9/strnstr.9
new file mode 100644 (file)
index 0000000..70cbd65
--- /dev/null
@@ -0,0 +1,90 @@
+.\"    $OpenBSD: strnstr.9,v 1.1 2023/12/21 02:57:14 jsg Exp $
+.\"
+.\" Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
+.\" Copyright (c) 1990, 1991, 1993
+.\"    The Regents of the University of California.  All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Chris Torek and the American National Standards Committee X3,
+.\" on Information Processing Systems.
+.\"
+.\" 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. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+.\"
+.Dd $Mdocdate: December 21 2023 $
+.Dt STRNSTR 9
+.Os
+.Sh NAME
+.Nm strnstr
+.Nd locate a substring in a string
+.Sh SYNOPSIS
+.In lib/libkern/libkern.h
+.Ft char *
+.Fn strnstr "const char *big" "const char *little" "size_t len"
+.Sh DESCRIPTION
+The
+.Fn strnstr
+function
+locates the first occurrence of the null-terminated string
+.Fa little
+in the string
+.Fa big ,
+where not more than
+.Fa len
+characters are searched.
+Characters that appear after a
+.Ql \e0
+character are not searched.
+.Sh RETURN VALUES
+If
+.Fa little
+is an empty string,
+.Fa big
+is returned;
+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 EXAMPLES
+The following sets the pointer
+.Va ptr
+to
+.Dv NULL ,
+because only the first 4 characters of
+.Va largestring
+are searched:
+.Bd -literal -offset indent
+const char *largestring = "Foo Bar Baz";
+const char *smallstring = "Bar";
+char *ptr;
+
+ptr = strnstr(largestring, smallstring, 4);
+.Ed
+.Sh SEE ALSO
+.Xr memchr 9
index 57a6f6a..b05d6bc 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: files,v 1.726 2023/11/21 14:00:13 bluhm Exp $
+#      $OpenBSD: files,v 1.727 2023/12/21 02:57:14 jsg Exp $
 #      $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
 
 #      @(#)files.newconf       7.5 (Berkeley) 5/10/93
@@ -1075,6 +1075,7 @@ file lib/libkern/arch/${MACHINE_ARCH}/strlen.S | lib/libkern/strlen.c
 file lib/libkern/arch/${MACHINE_ARCH}/strncmp.S | lib/libkern/strncmp.c
 file lib/libkern/arch/${MACHINE_ARCH}/strncpy.S | lib/libkern/strncpy.c
 file lib/libkern/arch/${MACHINE_ARCH}/strnlen.S | lib/libkern/strnlen.c
+file lib/libkern/arch/${MACHINE_ARCH}/strnstr.S | lib/libkern/strnstr.c
 file lib/libkern/arch/${MACHINE_ARCH}/scanc.S | lib/libkern/scanc.c
 file lib/libkern/arch/${MACHINE_ARCH}/skpc.S | lib/libkern/skpc.c
 file lib/libkern/arch/${MACHINE_ARCH}/htonl.S | lib/libkern/htonl.c
index 597219a..fb5d691 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: libkern.h,v 1.36 2020/02/26 14:23:15 visa Exp $       */
+/*     $OpenBSD: libkern.h,v 1.37 2023/12/21 02:57:14 jsg Exp $        */
 /*     $NetBSD: libkern.h,v 1.7 1996/03/14 18:52:08 christos Exp $     */
 
 /*-
@@ -167,5 +167,6 @@ size_t       getsn(char *, size_t)
 char   *strchr(const char *, int);
 char   *strrchr(const char *, int);
 int     timingsafe_bcmp(const void *, const void *, size_t);
+char   *strnstr(const char *, const char *, size_t);
 
 #endif /* __LIBKERN_H__ */
diff --git a/sys/lib/libkern/strnstr.c b/sys/lib/libkern/strnstr.c
new file mode 100644 (file)
index 0000000..abba78e
--- /dev/null
@@ -0,0 +1,62 @@
+/*     $OpenBSD: strnstr.c,v 1.1 2023/12/21 02:57:14 jsg Exp $ */
+
+/*-
+ * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
+ * Copyright (c) 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * 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. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 <sys/param.h>
+#include <lib/libkern/libkern.h>
+
+/*
+ * Find the first occurrence of find in s, where the search is limited to the
+ * first slen characters of s.
+ */
+char *
+strnstr(const char *s, const char *find, size_t slen)
+{
+       char c, sc;
+       size_t len;
+
+       if ((c = *find++) != '\0') {
+               len = strlen(find);
+               do {
+                       do {
+                               if (slen-- < 1 || (sc = *s++) == '\0')
+                                       return (NULL);
+                       } while (sc != c);
+                       if (len > slen)
+                               return (NULL);
+               } while (strncmp(s, find, len) != 0);
+               s--;
+       }
+       return ((char *)s);
+}