diff --git a/doc/contribute/coding_guidelines/index.rst b/doc/contribute/coding_guidelines/index.rst index 1b9065215d297..8926e40b674ea 100644 --- a/doc/contribute/coding_guidelines/index.rst +++ b/doc/contribute/coding_guidelines/index.rst @@ -1284,6 +1284,7 @@ Description :header: Function,Source :widths: auto + `fnmatch()`_, POSIX.1-2008 `gmtime_r()`_,POSIX.1-2001 `strnlen()`_,POSIX.1-2008 `strtok_r()`_,POSIX.1-2001 @@ -1309,6 +1310,7 @@ Rationale toolchains that come with their own C standard libraries. .. _main Zephyr repository: https://github.com/zephyrproject-rtos/zephyr + .. _fnmatch(): https://pubs.opengroup.org/onlinepubs/9699919799/functions/fnmatch.html .. _gmtime_r(): https://pubs.opengroup.org/onlinepubs/9699919799/functions/gmtime_r.html .. _strnlen(): https://pubs.opengroup.org/onlinepubs/9699919799/functions/strlen.html .. _strtok_r(): https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtok.html diff --git a/include/zephyr/posix/fnmatch.h b/include/zephyr/posix/fnmatch.h index 41e77aa70c149..c0fb76d0fd715 100644 --- a/include/zephyr/posix/fnmatch.h +++ b/include/zephyr/posix/fnmatch.h @@ -1,59 +1,12 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ - -/* $NetBSD: fnmatch.h,v 1.12.50.1 2011/02/08 16:18:55 bouyer Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. 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. 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. +/* + * Copyright (c) 2025 The Zephyr Project Contributors * - * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93 + * SPDX-License-Identifier: Apache-2.0 */ -#ifndef _FNMATCH_H_ -#define _FNMATCH_H_ - -#define FNM_NOMATCH 1 /* Match failed. */ -#define FNM_NOSYS 2 /* Function not implemented. */ -#define FNM_NORES 3 /* Out of resources */ - -#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ -#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ -#define FNM_PERIOD 0x04 /* Period must be matched by period. */ -#define FNM_CASEFOLD 0x08 /* Pattern is matched case-insensitive */ -#define FNM_LEADING_DIR 0x10 /* Ignore / after Imatch. */ - -#ifdef __cplusplus -extern "C" { -#endif - -int fnmatch(const char *, const char *, int); +#ifndef ZEPHYR_INCLUDE_POSIX_FNMATCH_H_ +#define ZEPHYR_INCLUDE_POSIX_FNMATCH_H_ -#ifdef __cplusplus -} -#endif +#include_next -#endif /* !_FNMATCH_H_ */ +#endif /* ZEPHYR_INCLUDE_POSIX_FNMATCH_H_ */ diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 62f5f33415137..3b4066ad636b4 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -90,6 +90,7 @@ config MINIMAL_LIBC imply COMPILER_FREESTANDING select COMMON_LIBC_ABORT select COMMON_LIBC_STRNLEN + select COMMON_LIBC_FNMATCH imply COMMON_LIBC_MALLOC imply COMMON_LIBC_CALLOC imply COMMON_LIBC_REALLOCARRAY @@ -119,6 +120,7 @@ config NEWLIB_LIBC depends on NEWLIB_LIBC_SUPPORTED select NEED_LIBC_MEM_PARTITION select TC_PROVIDES_POSIX_C_LANG_SUPPORT_R + select COMMON_LIBC_FNMATCH imply POSIX_DEVICE_IO_ALIAS_CLOSE imply POSIX_DEVICE_IO_ALIAS_OPEN imply POSIX_DEVICE_IO_ALIAS_READ @@ -137,6 +139,7 @@ config ARCMWDT_LIBC depends on "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "arcmwdt" select STATIC_INIT_GNU select LIBC_ALLOW_LESS_THAN_64BIT_TIME + select COMMON_LIBC_FNMATCH help C library provided by ARC MWDT toolchain. @@ -151,6 +154,7 @@ config IAR_LIBC depends on "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "iar" select COMMON_LIBC_STRNLEN select COMMON_LIBC_TIME + select COMMON_LIBC_FNMATCH help Use the full IAR Compiler runtime libraries. A reduced Zephyr minimal libc will be used for library functionality diff --git a/lib/libc/common/CMakeLists.txt b/lib/libc/common/CMakeLists.txt index ed3d28fe5a622..79a72ca9139f8 100644 --- a/lib/libc/common/CMakeLists.txt +++ b/lib/libc/common/CMakeLists.txt @@ -12,6 +12,12 @@ zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_CTIME source/time/ctime.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_TIME source/time/time.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_MALLOC source/stdlib/malloc.c) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_STRNLEN source/string/strnlen.c) + +if(CONFIG_COMMON_LIBC_FNMATCH) + zephyr_library_sources(source/fnmatch/fnmatch.c) + zephyr_include_directories(source/fnmatch/include) +endif() + zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_THRD source/thrd/cnd.c source/thrd/mtx.c diff --git a/lib/libc/common/Kconfig b/lib/libc/common/Kconfig index c4ac88dbab1cd..dee39201081c3 100644 --- a/lib/libc/common/Kconfig +++ b/lib/libc/common/Kconfig @@ -104,6 +104,11 @@ config COMMON_LIBC_STRNLEN help common implementation of strnlen(). +config COMMON_LIBC_FNMATCH + bool + help + common implementation of fnmatch(). + config COMMON_LIBC_THRD bool "C11 API support" depends on DYNAMIC_THREAD diff --git a/lib/posix/c_lib_ext/fnmatch.c b/lib/libc/common/source/fnmatch/fnmatch.c similarity index 99% rename from lib/posix/c_lib_ext/fnmatch.c rename to lib/libc/common/source/fnmatch/fnmatch.c index 911b6f41afa70..54292ce67e9a8 100644 --- a/lib/posix/c_lib_ext/fnmatch.c +++ b/lib/libc/common/source/fnmatch/fnmatch.c @@ -39,11 +39,13 @@ * Compares a filename or pathname to a pattern. */ +#define _GNU_SOURCE + #include #include #include -#include +#include #include #define EOS '\0' diff --git a/lib/libc/common/source/fnmatch/include/fnmatch.h b/lib/libc/common/source/fnmatch/include/fnmatch.h new file mode 100644 index 0000000000000..9f43fa7575d02 --- /dev/null +++ b/lib/libc/common/source/fnmatch/include/fnmatch.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +/* $NetBSD: fnmatch.h,v 1.12.50.1 2011/02/08 16:18:55 bouyer Exp $ */ + +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. 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. 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. + * + * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _ZEPHYR_LIB_LIBC_COMMON_SOURCE_FNMATCH_INCLUDE_FNMATCH_H_ +#define _ZEPHYR_LIB_LIBC_COMMON_SOURCE_FNMATCH_INCLUDE_FNMATCH_H_ + +#define FNM_NOMATCH 1 /* Match failed. */ +#define FNM_NOSYS 2 /* Function not implemented. */ +#define FNM_NORES 3 /* Out of resources */ + +#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ +#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ +#define FNM_PERIOD 0x04 /* Period must be matched by period. */ + +#if defined(_GNU_SOURCE) +#define FNM_CASEFOLD 0x08 /* Pattern is matched case-insensitive */ +#define FNM_LEADING_DIR 0x10 /* Ignore / after Imatch. */ +#endif /* _GNU_SOURCE */ + +#ifdef __cplusplus +extern "C" { +#endif + +int fnmatch(const char *, const char *, int); + +#ifdef __cplusplus +} +#endif + +#endif /* !_ZEPHYR_LIB_LIBC_COMMON_SOURCE_FNMATCH_INCLUDE_FNMATCH_H_ */ diff --git a/lib/posix/c_lib_ext/CMakeLists.txt b/lib/posix/c_lib_ext/CMakeLists.txt index ee0581cb22246..f4c159710c45b 100644 --- a/lib/posix/c_lib_ext/CMakeLists.txt +++ b/lib/posix/c_lib_ext/CMakeLists.txt @@ -8,7 +8,6 @@ endif() zephyr_library() zephyr_library_sources( - fnmatch.c getentropy.c getopt/getopt.c getopt/getopt_common.c diff --git a/subsys/net/lib/http/Kconfig b/subsys/net/lib/http/Kconfig index f36fb6d053934..01091a2980b51 100644 --- a/subsys/net/lib/http/Kconfig +++ b/subsys/net/lib/http/Kconfig @@ -166,8 +166,6 @@ config HTTP_SERVER_WEBSOCKET config HTTP_SERVER_RESOURCE_WILDCARD bool "Allow wildcard matching of resources" - # The POSIX_C_LIB_EXT will get fnmatch() support - select POSIX_C_LIB_EXT help Allow user to specify wildcards when setting up resource strings. This means that instead of specifying multiple resources with exact diff --git a/subsys/net/lib/http/http_server_core.c b/subsys/net/lib/http/http_server_core.c index 8010dd9f88e72..43484760dc45d 100644 --- a/subsys/net/lib/http/http_server_core.c +++ b/subsys/net/lib/http/http_server_core.c @@ -5,6 +5,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define _GNU_SOURCE /* for FNM_LEADING_DIR in fnmatch.h */ +#include #include #include #include @@ -21,7 +23,6 @@ #include #include #include -#include #include LOG_MODULE_REGISTER(net_http_server, CONFIG_NET_HTTP_SERVER_LOG_LEVEL); diff --git a/subsys/shell/Kconfig b/subsys/shell/Kconfig index c35b0193f6b4b..bfa450c8c23b7 100644 --- a/subsys/shell/Kconfig +++ b/subsys/shell/Kconfig @@ -146,7 +146,6 @@ config SHELL_ASCII_FILTER config SHELL_WILDCARD bool "Wildcard support in shell" - select POSIX_C_LIB_EXT default y if !SHELL_MINIMAL help Enables using wildcards: * and ? in the shell. diff --git a/subsys/shell/shell_wildcard.c b/subsys/shell/shell_wildcard.c index cfa23d00f782b..bb6846d9fccaa 100644 --- a/subsys/shell/shell_wildcard.c +++ b/subsys/shell/shell_wildcard.c @@ -5,7 +5,8 @@ */ #include -#include +#include + #include "shell_wildcard.h" #include "shell_utils.h" #include "shell_ops.h" diff --git a/subsys/testsuite/coverage/coverage.c b/subsys/testsuite/coverage/coverage.c index 9b9fcc632cb5c..f189a720e8e95 100644 --- a/subsys/testsuite/coverage/coverage.c +++ b/subsys/testsuite/coverage/coverage.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include "coverage.h" #include #include diff --git a/tests/posix/c_lib_ext/src/fnmatch.c b/tests/posix/c_lib_ext/src/fnmatch.c index 42c84d7ca1a0f..f0ab323b7b4e7 100644 --- a/tests/posix/c_lib_ext/src/fnmatch.c +++ b/tests/posix/c_lib_ext/src/fnmatch.c @@ -30,8 +30,20 @@ ZTEST(posix_c_lib_ext, test_fnmatch) zassert_equal(fnmatch("a*.c", "a/x.c", FNM_PATHNAME), FNM_NOMATCH); zassert_ok(fnmatch("*/foo", "/foo", FNM_PATHNAME)); zassert_ok(fnmatch("-O[01]", "-O1", 0)); - zassert_ok(fnmatch("[[?*\\]", "\\", 0)); - zassert_ok(fnmatch("[]?*\\]", "]", 0)); + if (!IS_ENABLED(CONFIG_COMMON_LIBC_FNMATCH)) { + /* \\ escapes ], no bracket expr, no match */ + zassert_equal(fnmatch("[[?*\\]", "\\", 0), FNM_NOMATCH); + /* \\ escapes ], no bracket expr, no match */ + zassert_equal(fnmatch("[]?*\\]", "]", 0), FNM_NOMATCH); + } + /* \\ unescaped, match */ + zassert_ok(fnmatch("[[?*\\]", "\\", FNM_NOESCAPE)); + /* \\ escapes \\, match */ + zassert_ok(fnmatch("[[?*\\\\]", "\\", 0)); + /* \\ unescaped, match */ + zassert_ok(fnmatch("[]?*\\]", "]", FNM_NOESCAPE)); + /* \\ escapes \\, match */ + zassert_ok(fnmatch("[]?*\\\\]", "]", 0)); zassert_ok(fnmatch("[!]a-]", "b", 0)); zassert_ok(fnmatch("[]-_]", "^", 0)); zassert_ok(fnmatch("[!]-_]", "X", 0)); @@ -73,9 +85,14 @@ ZTEST(posix_c_lib_ext, test_fnmatch) zassert_equal(fnmatch("*/*", "a/.b", FNM_PATHNAME | FNM_PERIOD), FNM_NOMATCH); zassert_ok(fnmatch("*?*/*", "a/.b", FNM_PERIOD)); zassert_ok(fnmatch("*[.]/b", "a./b", FNM_PATHNAME | FNM_PERIOD)); - /* zassert_ok(fnmatch("*[[:alpha:]]/""*[[:alnum:]]", "a/b", FNM_PATHNAME)); */ - zassert_not_equal(fnmatch("*[![:digit:]]*/[![:d-d]", "a/b", FNM_PATHNAME), 0); - zassert_not_equal(fnmatch("*[![:digit:]]*/[[:d-d]", "a/[", FNM_PATHNAME), 0); + + /* Disable tests that fail when using Zephyr's fnmatch implementation */ + if (!IS_ENABLED(CONFIG_POSIX_C_LIB_EXT)) { + zassert_ok(fnmatch("*[[:alpha:]]/""*[[:alnum:]]", "a/b", FNM_PATHNAME)); + zassert_ok(fnmatch("*[![:digit:]]*/[![:d-d]", "a/b", FNM_PATHNAME)); + zassert_ok(fnmatch("*[![:digit:]]*/[[:d-d]", "a/[", FNM_PATHNAME)); + } + zassert_not_equal(fnmatch("*[![:digit:]]*/[![:d-d]", "a/[", FNM_PATHNAME), 0); zassert_ok(fnmatch("a?b", "a.b", FNM_PATHNAME | FNM_PERIOD)); zassert_ok(fnmatch("a*b", "a.b", FNM_PATHNAME | FNM_PERIOD));