untrusted comment: verify with signify key from https://research.exoticsilicon.com RWRn5d3Yx35u09kO7pGDkvsoX6kZwcWJkrlZsyZOr0AEk2Xar6Jfsnb2JJoZXhnXknse3egH5ZfgAQWa3y232//zUPCZu5uXuQs= --- include/string.h +++ include/string.h @@ -131,6 +131,7 @@ __attribute__ ((__bounded__(__buffer__,1,2))); void *memrchr(const void *, int, size_t); char *strcasestr(const char *, const char *); +char *strchrnul(const char *, int); void strmode(__mode_t, char *); char *strsep(char **, const char *); int timingsafe_bcmp(const void *, const void *, size_t); --- lib/libc/hidden/string.h +++ lib/libc/hidden/string.h @@ -46,6 +46,7 @@ PROTO_NORMAL(strcasestr); PROTO_STD_DEPRECATED(strcat); PROTO_NORMAL(strchr); +PROTO_NORMAL(strchrnul); PROTO_NORMAL(strcmp); PROTO_NORMAL(strcoll); PROTO_DEPRECATED(strcoll_l); --- lib/libc/string/Makefile.inc +++ lib/libc/string/Makefile.inc @@ -4,8 +4,8 @@ .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/string ${LIBCSRCDIR}/string SRCS+= explicit_bzero.c memccpy.c memmem.c memrchr.c stpcpy.c stpncpy.c \ - strcasecmp.c strcasecmp_l.c strcasestr.c strcoll.c strcoll_l.c \ - strdup.c strerror.c strerror_l.c strerror_r.c strmode.c \ + strcasecmp.c strcasecmp_l.c strcasestr.c strchrnul.c strcoll.c \ + strcoll_l.c strdup.c strerror.c strerror_l.c strerror_r.c strmode.c \ strndup.c strnlen.c strsignal.c strtok.c strxfrm.c strxfrm_l.c \ timingsafe_bcmp.c timingsafe_memcmp.c \ wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \ --- lib/libc/string/strchrnul.c +++ lib/libc/string/strchrnul.c @@ -0,0 +1,47 @@ +/* + * Copyright 2026, Exotic Silicon, all rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. This software is licensed exclusively under this specific license text. + * The license text may not be changed, and the software including modified + * versions may not be re-licensed under any other license text. + * 2. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * 3. 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. + * 4. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: This product includes software + * developed by Exotic Silicon. + * 5. The name of Exotic Silicon must not be used to endorse or promote products + * derived from this software without specific prior written permission. + * 6. Redistributions of modified versions of the source code must be clearly + * identified as having been modified from the original. + * 7. Redistributions in binary form that have been created from modified + * versions of the source code must clearly state in the documentation and/or + * other materials provided with the distribution that the source code has + * been modified from the original. + * + * THIS SOFTWARE IS PROVIDED '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 + * EXOTIC SILICON 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 + +char * strchrnul(const char * p, int c) { + for ( ; ; p++) + if (*p == (char)c || *p == 0) + return ((char *)p); + } + +DEF_STRONG(strchrnul); --- lib/libc/string/strchr.3 +++ lib/libc/string/strchr.3 @@ -31,24 +31,29 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd $Mdocdate: December 11 2024 $ +.Dd $Mdocdate: February 28 2026 $ .Dt STRCHR 3 .Os .Sh NAME .Nm strchr , +.Nm strchrnul , .Nm index .Nd locate first occurrence of a character in a string .Sh SYNOPSIS .In string.h .Ft char * .Fn strchr "const char *s" "int c" +.Ft char * +.Fn strchrnul "const char *s" "int c" .In strings.h .Ft char * .Fn index "const char *s" "int c" .Sh DESCRIPTION The .Fn strchr -function locates the first occurrence of the character +and +.Fn strchrnul +functions locate the first occurrence of the character .Fa c .Pq converted to a char in the string @@ -58,10 +63,21 @@ .Fa c is .Ql \e0 , +both .Fn strchr -locates the terminating +and +.Fn strchrnul +locate the terminating .Ql \e0 . .Pp +.Fn strchr +and +.Fn strchrnul +differ in their handling of the case where the character is not matched. +See the +.Sx RETURN VALUES +section for more details. +.Pp The .Fn index function is an old synonym for @@ -72,6 +88,11 @@ function returns a pointer to the located character or .Dv NULL if the character does not appear in the string. +.Pp +The +.Fn strchrnul +function returns a pointer to the located character or a pointer to the +terminating NUL of the provided string if the character does not appear in it. .Sh EXAMPLES After the following call to .Fn strchr , @@ -114,3 +135,12 @@ .At III and was reimplemented for .Bx 4.3 . +.Pp +This manual page has been updated as part of a patchset written by Exotic Silicon in 2026, +which implements +.Fn strchrnul +on +.Ox 7.8 +.Pp +For more information on the above mentioned patchset, please refer to +https://research.exoticsilicon.com/articles/adding_strchrnul_to_libc --- lib/libc/Symbols.list +++ lib/libc/Symbols.list @@ -1625,6 +1625,7 @@ strcasestr strcat strchr +strchrnul strcmp strcoll strcoll_l --- regress/lib/libc/strchrnul/Makefile +++ regress/lib/libc/strchrnul/Makefile @@ -0,0 +1,3 @@ +PROG= strchrnultest + +.include --- regress/lib/libc/strchrnul/strchrnultest.c +++ regress/lib/libc/strchrnul/strchrnultest.c @@ -0,0 +1,79 @@ +/* + * Copyright 2026, Exotic Silicon, all rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. This software is licensed exclusively under this specific license text. + * The license text may not be changed, and the software including modified + * versions may not be re-licensed under any other license text. + * 2. Redistributions of source code must retain the above copyright notice, + * this list of conditions, and the following disclaimer. + * 3. 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. + * 4. All advertising materials mentioning features or use of this software must + * display the following acknowledgement: This product includes software + * developed by Exotic Silicon. + * 5. The name of Exotic Silicon must not be used to endorse or promote products + * derived from this software without specific prior written permission. + * 6. Redistributions of modified versions of the source code must be clearly + * identified as having been modified from the original. + * 7. Redistributions in binary form that have been created from modified + * versions of the source code must clearly state in the documentation and/or + * other materials provided with the distribution that the source code has + * been modified from the original. + * + * THIS SOFTWARE IS PROVIDED '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 + * EXOTIC SILICON 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 +#include +#include + +#define TEST_STRING "This is a long string" + +int main() +{ +char * foo = TEST_STRING; + +/* + * Searching for ... + */ + +/* + * ... the first space + */ +assert(strchrnul(foo, ' ') == foo + 4); + +/* + * A character not in the test string - should return the final NUL + */ +assert(strchrnul(foo, 'X') == foo + sizeof(TEST_STRING) - 1); + +/* + * ... 0x00 in the test string + */ +assert((strchrnul(foo, 0)) == foo + sizeof(TEST_STRING) - 1); + +/* + * ... 0x00 in an empty string + */ +assert(*(strchrnul("", 0)) == 0); + +/* + * ... 0xFF in an empty string + */ +assert(*(strchrnul("", 0xff)) == 0); + +return (0); +} --- regress/lib/libc/Makefile +++ regress/lib/libc/Makefile @@ -20,7 +20,8 @@ SUBDIR+= qsort SUBDIR+= regex SUBDIR+= setjmp setjmp-signal sigsetjmp sigthr sleep sprintf stdio -SUBDIR+= stdio_threading stpncpy strchr strerror strlcat strlcpy strnlen +SUBDIR+= stdio_threading stpncpy strchr strchrnul strerror strlcat strlcpy +SUBDIR+= strnlen SUBDIR+= strtod strtol strtonum sys SUBDIR+= telldir time timingsafe SUBDIR+= uuid