From 7d7ac6d7f5137f4d7745b0c98946a5ca8e991f3c Mon Sep 17 00:00:00 2001 From: Christopher Friedt Date: Sun, 24 Dec 2023 11:00:24 -0500 Subject: [PATCH] libc: minimal: errno.h, strerror to common, strerror_r to posix The strerror_r() function is POSIX. It's not part of ISO C. Moreover, the versions available in both Newlib and Picolibc do not seem to comply with the POSIX specification OOTB. Moving this function to lib/posix ensures that Zephyr applications have a consistent implementation of the POSIX API. Signed-off-by: Christopher Friedt --- doc/develop/languages/c/common_libc.rst | 24 +++++++++ doc/develop/languages/c/minimal_libc.rst | 25 ---------- doc/zephyr.doxyfile.in | 1 + include/zephyr/sys/errno_private.h | 2 + lib/CMakeLists.txt | 2 - lib/libc/Kconfig | 3 ++ lib/libc/common/CMakeLists.txt | 18 +++++++ lib/libc/common/Kconfig | 16 ++++++ lib/libc/{minimal => common}/include/errno.h | 6 +-- lib/libc/common/source/string/strerror.c | 30 +++++++++++ lib/libc/minimal/CMakeLists.txt | 16 ------ lib/libc/minimal/Kconfig | 13 ++--- lib/libc/minimal/include/string.h | 2 + lib/posix/CMakeLists.txt | 1 + lib/posix/Kconfig | 3 ++ lib/posix/Kconfig.cx.string | 15 ++++++ .../string/strerror.c => posix/strerror_r.c} | 17 +------ scripts/build/gen_strerror_table.py | 26 ++++++++-- scripts/ci/errno.py | 12 ++--- tests/lib/c_lib/common/prj.conf | 2 - tests/lib/c_lib/strerror/Kconfig | 16 ------ tests/lib/c_lib/strerror/src/main.c | 50 +------------------ tests/lib/c_lib/strerror/testcase.yaml | 4 +- tests/posix/cx/CMakeLists.txt | 8 +++ tests/posix/cx/prj.conf | 2 + tests/posix/cx/src/string/_main.c | 9 ++++ tests/posix/cx/src/string/strerror_r.c | 46 +++++++++++++++++ 27 files changed, 223 insertions(+), 146 deletions(-) rename lib/libc/{minimal => common}/include/errno.h (97%) create mode 100644 lib/libc/common/source/string/strerror.c create mode 100644 lib/posix/Kconfig.cx.string rename lib/{libc/minimal/source/string/strerror.c => posix/strerror_r.c} (67%) delete mode 100644 tests/lib/c_lib/strerror/Kconfig create mode 100644 tests/posix/cx/CMakeLists.txt create mode 100644 tests/posix/cx/prj.conf create mode 100644 tests/posix/cx/src/string/_main.c create mode 100644 tests/posix/cx/src/string/strerror_r.c diff --git a/doc/develop/languages/c/common_libc.rst b/doc/develop/languages/c/common_libc.rst index 643265a63e1888b..fe4b3910f1f87e0 100644 --- a/doc/develop/languages/c/common_libc.rst +++ b/doc/develop/languages/c/common_libc.rst @@ -45,3 +45,27 @@ The standard dynamic memory management interface functions implemented by the common C library are thread safe and may be simultaneously called by multiple threads. These functions are implemented in :file:`lib/libc/common/source/stdlib/malloc.c`. + +Error numbers +************* + +Error numbers are used throughout Zephyr APIs to signal error conditions as +return values from functions. They are typically returned as the negative value +of the integer literals defined in this section, and are defined in the +:file:`errno.h` header file. + +A subset of the error numbers defined in the `POSIX errno.h specification`_ and +other de-facto standard sources have been added to the common libc resources. + +A conscious effort is made in Zephyr to keep the values of the common libc +error numbers consistent with the different implementations of the C standard +libraries supported by Zephyr. The minimal libc :file:`errno.h` is checked +against that of the :ref:`Newlib ` to ensure that the error +numbers are kept aligned. + +Below is a list of the error number definitions. For the actual numeric values +please refer to :file:`lib/libc/common/include/errno.h`. + +.. doxygengroup:: system_errno + +.. _`POSIX errno.h specification`: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html diff --git a/doc/develop/languages/c/minimal_libc.rst b/doc/develop/languages/c/minimal_libc.rst index dbfd2ab7b727774..f4886efaafcc74f 100644 --- a/doc/develop/languages/c/minimal_libc.rst +++ b/doc/develop/languages/c/minimal_libc.rst @@ -40,28 +40,3 @@ Dynamic Memory Management The minimal libc uses the malloc api family implementation provided by the :ref:`common C library `, which itself is built upon the :ref:`kernel memory heap API `. - -Error numbers -************* - -Error numbers are used throughout Zephyr APIs to signal error conditions as -return values from functions. They are typically returned as the negative value -of the integer literals defined in this section, and are defined in the -:file:`errno.h` header file. - -A subset of the error numbers defined in the `POSIX errno.h specification`_ and -other de-facto standard sources have been added to the minimal libc. - -A conscious effort is made in Zephyr to keep the values of the minimal libc -error numbers consistent with the different implementations of the C standard -libraries supported by Zephyr. The minimal libc :file:`errno.h` is checked -against that of the :ref:`Newlib ` to ensure that the error -numbers are kept aligned. - -Below is a list of the error number definitions. For the actual numeric values -please refer to `errno.h`_. - -.. doxygengroup:: system_errno - -.. _`POSIX errno.h specification`: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html -.. _`errno.h`: https://github.com/zephyrproject-rtos/zephyr/blob/main/lib/libc/minimal/include/errno.h diff --git a/doc/zephyr.doxyfile.in b/doc/zephyr.doxyfile.in index 1f8a6af46c48aa1..a88d4c9d99d5f71 100644 --- a/doc/zephyr.doxyfile.in +++ b/doc/zephyr.doxyfile.in @@ -924,6 +924,7 @@ INPUT = @ZEPHYR_BASE@/doc/_doxygen/mainpage.md \ @ZEPHYR_BASE@/doc/_doxygen/groups.dox \ @ZEPHYR_BASE@/kernel/include/kernel_arch_interface.h \ @ZEPHYR_BASE@/include/ \ + @ZEPHYR_BASE@/lib/libc/common/include/ \ @ZEPHYR_BASE@/lib/libc/minimal/include/ \ @ZEPHYR_BASE@/subsys/testsuite/include/ \ @ZEPHYR_BASE@/subsys/testsuite/ztest/include/ diff --git a/include/zephyr/sys/errno_private.h b/include/zephyr/sys/errno_private.h index 60df9622bb81da3..f13ac6d51706f40 100644 --- a/include/zephyr/sys/errno_private.h +++ b/include/zephyr/sys/errno_private.h @@ -20,6 +20,8 @@ extern "C" { #ifdef CONFIG_LIBC_ERRNO #include +extern int __thread errno; + static inline int *z_errno(void) { return &errno; diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 7a0ee04e4acda64..0d6c069fcbbe7e7 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -4,9 +4,7 @@ add_compile_options($) add_subdirectory(crc) -if(NOT CONFIG_EXTERNAL_LIBC) add_subdirectory(libc) -endif() if(NOT CONFIG_NATIVE_LIBC) add_subdirectory(posix) endif() diff --git a/lib/libc/Kconfig b/lib/libc/Kconfig index 8b71808ff54845b..e4ea4506349a421 100644 --- a/lib/libc/Kconfig +++ b/lib/libc/Kconfig @@ -74,6 +74,7 @@ config MINIMAL_LIBC imply COMPILER_FREESTANDING select COMMON_LIBC_ABORT select COMMON_LIBC_STRNLEN + select COMMON_LIBC_STRERROR help Build with minimal C library. @@ -86,6 +87,7 @@ config PICOLIBC imply COMMON_LIBC_MALLOC depends on !NATIVE_APPLICATION depends on PICOLIBC_SUPPORTED + select COMMON_LIBC_STRERROR help Build with picolibc library. The picolibc library is built as a module if PICOLIBC_MODULE is set, otherwise picolibc is @@ -97,6 +99,7 @@ config NEWLIB_LIBC depends on !NATIVE_APPLICATION depends on NEWLIB_LIBC_SUPPORTED select NEED_LIBC_MEM_PARTITION + select COMMON_LIBC_STRERROR help Build with newlib library. The newlib library is expected to be part of the SDK in this case. diff --git a/lib/libc/common/CMakeLists.txt b/lib/libc/common/CMakeLists.txt index 4b101d8b84bdc97..64b2877d2f569c6 100644 --- a/lib/libc/common/CMakeLists.txt +++ b/lib/libc/common/CMakeLists.txt @@ -2,12 +2,19 @@ zephyr_system_include_directories(include) +set(GEN_DIR ${ZEPHYR_BINARY_DIR}/include/generated) +set(STRERROR_TABLE_H ${GEN_DIR}/libc/common/strerror_table.h) + zephyr_library() zephyr_library_property(ALLOW_EMPTY TRUE) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_ABORT source/stdlib/abort.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) +zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_STRERROR + ${STRERROR_TABLE_H} + source/string/strerror.c + ) zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_THRD source/thrd/cnd.c source/thrd/mtx.c @@ -18,3 +25,14 @@ zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_THRD # Prevent compiler from optimizing calloc into an infinite recursive call zephyr_library_compile_options($) + +add_custom_command( + OUTPUT ${STRERROR_TABLE_H} + COMMAND + ${PYTHON_EXECUTABLE} + ${ZEPHYR_BASE}/scripts/build/gen_strerror_table.py + -i include/errno.h + -o ${STRERROR_TABLE_H} + DEPENDS include/errno.h + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/lib/libc/common/Kconfig b/lib/libc/common/Kconfig index dc22d0c2108d5f1..14641022cb4ffad 100644 --- a/lib/libc/common/Kconfig +++ b/lib/libc/common/Kconfig @@ -68,6 +68,22 @@ config COMMON_LIBC_STRNLEN help common implementation of strnlen(). +config COMMON_LIBC_STRERROR + bool "Common C library strerror" + default y + help + common implementation of strerror(). + +config COMMON_LIBC_STRING_ERROR_TABLE + bool "String error table for strerror()" + depends on COMMON_LIBC_STRERROR + help + Select this option to ensure that strerror() produces strings corresponding to the + descriptions in errno.h. + + The string error table can add ~2kiB to ROM. As such, it is disabled by default. In this + case, strerror() is still present but it produces an empty string. + config COMMON_LIBC_THRD bool "C11 API support" depends on DYNAMIC_THREAD diff --git a/lib/libc/minimal/include/errno.h b/lib/libc/common/include/errno.h similarity index 97% rename from lib/libc/minimal/include/errno.h rename to lib/libc/common/include/errno.h index 6b4ffda4937e576..bdd2a3d6ddc48e9 100644 --- a/lib/libc/minimal/include/errno.h +++ b/lib/libc/common/include/errno.h @@ -17,8 +17,8 @@ * @brief System error numbers */ -#ifndef ZEPHYR_LIB_LIBC_MINIMAL_INCLUDE_ERRNO_H_ -#define ZEPHYR_LIB_LIBC_MINIMAL_INCLUDE_ERRNO_H_ +#ifndef ZEPHYR_LIB_LIBC_COMMON_INCLUDE_ERRNO_H_ +#define ZEPHYR_LIB_LIBC_COMMON_INCLUDE_ERRNO_H_ /** * @brief System error numbers @@ -127,4 +127,4 @@ extern "C" { } #endif -#endif /* ZEPHYR_LIB_LIBC_MINIMAL_INCLUDE_ERRNO_H_ */ +#endif /* ZEPHYR_LIB_LIBC_COMMON_INCLUDE_ERRNO_H_ */ diff --git a/lib/libc/common/source/string/strerror.c b/lib/libc/common/source/string/strerror.c new file mode 100644 index 000000000000000..62b83a1442462b9 --- /dev/null +++ b/lib/libc/common/source/string/strerror.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +/* + * See scripts/build/gen_strerror_table.py + * + * #define sys_nerr N + * const char *const sys_errlist[sys_nerr]; + * const uint8_t sys_errlen[sys_nerr]; + */ +#define __sys_errlist_declare +#include "libc/common/strerror_table.h" + +char *strerror(int errnum) +{ + if (IS_ENABLED(CONFIG_COMMON_LIBC_STRING_ERROR_TABLE) && errnum >= 0 && errnum < sys_nerr) { + return (char *)sys_errlist[errnum]; + } + + return (char *) ""; +} diff --git a/lib/libc/minimal/CMakeLists.txt b/lib/libc/minimal/CMakeLists.txt index abcab108e524e05..9422f5af47a78ac 100644 --- a/lib/libc/minimal/CMakeLists.txt +++ b/lib/libc/minimal/CMakeLists.txt @@ -4,9 +4,6 @@ zephyr_system_include_directories(include) zephyr_library() -set(GEN_DIR ${ZEPHYR_BINARY_DIR}/include/generated) -set(STRERROR_TABLE_H ${GEN_DIR}/libc/minimal/strerror_table.h) - zephyr_library_compile_options($) zephyr_library_sources( @@ -18,7 +15,6 @@ zephyr_library_sources( source/stdlib/bsearch.c source/stdlib/exit.c source/stdlib/qsort.c - source/string/strerror.c source/string/strncasecmp.c source/string/strstr.c source/string/string.c @@ -28,7 +24,6 @@ zephyr_library_sources( source/stdout/fprintf.c source/math/sqrtf.c source/math/sqrt.c - ${STRERROR_TABLE_H} ) if(CONFIG_MINIMAL_LIBC_TIME) @@ -36,14 +31,3 @@ if(CONFIG_MINIMAL_LIBC_TIME) endif() zephyr_library_sources_ifdef(CONFIG_MINIMAL_LIBC_RAND source/stdlib/rand.c) - -add_custom_command( - OUTPUT ${STRERROR_TABLE_H} - COMMAND - ${PYTHON_EXECUTABLE} - ${ZEPHYR_BASE}/scripts/build/gen_strerror_table.py - -i include/errno.h - -o ${STRERROR_TABLE_H} - DEPENDS include/errno.h - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -) diff --git a/lib/libc/minimal/Kconfig b/lib/libc/minimal/Kconfig index 29f95ee65bd29b2..34dc1c3fa9921b2 100644 --- a/lib/libc/minimal/Kconfig +++ b/lib/libc/minimal/Kconfig @@ -90,14 +90,11 @@ config MINIMAL_LIBC_TIME to set CONFIG_MINIMAL_LIBC_NON_REENTRANT_FUNCTIONS=y. config MINIMAL_LIBC_STRING_ERROR_TABLE - bool "String error table for strerror() and strerror_r()" + bool "String error table for strerror() [DEPRECATED]" + select DEPRECATED + select COMMON_LIBC_STRING_ERROR_TABLE help - Select this option to ensure that streror(), strerror_r() - produce strings corresponding to the descriptions in errno.h. - - The string error table can add ~2kiB to ROM. As such, it is - disabled by default. In this case, strerror() and strerror_r() - symbols are still present, but the functions produce an empty - string. + This option is deprecated. Use CONFIG_COMMON_LIBC_STRING_ERROR_TABLE + instead. endif # MINIMAL_LIBC diff --git a/lib/libc/minimal/include/string.h b/lib/libc/minimal/include/string.h index 35052c0c06c8f38..a0fc21c1c083a99 100644 --- a/lib/libc/minimal/include/string.h +++ b/lib/libc/minimal/include/string.h @@ -18,7 +18,9 @@ extern "C" { extern char *strcpy(char *ZRESTRICT d, const char *ZRESTRICT s); extern char *strerror(int errnum); +#if _POSIX_C_SOURCE >= 200112L extern int strerror_r(int errnum, char *strerrbuf, size_t buflen); +#endif extern char *strncpy(char *ZRESTRICT d, const char *ZRESTRICT s, size_t n); extern char *strchr(const char *s, int c); diff --git a/lib/posix/CMakeLists.txt b/lib/posix/CMakeLists.txt index e73c78d40e42977..0b79fb5708d9d0a 100644 --- a/lib/posix/CMakeLists.txt +++ b/lib/posix/CMakeLists.txt @@ -43,6 +43,7 @@ zephyr_library_sources_ifdef(CONFIG_POSIX_CLOCK clock.c) zephyr_library_sources_ifdef(CONFIG_POSIX_CLOCK nanosleep.c) zephyr_library_sources_ifdef(CONFIG_POSIX_CLOCK sleep.c) zephyr_library_sources_ifdef(CONFIG_POSIX_CLOCK timer.c) +zephyr_library_sources_ifdef(CONFIG_POSIX_CX_STRERROR_R strerror_r.c) zephyr_library_sources_ifdef(CONFIG_POSIX_FS fs.c) zephyr_library_sources_ifdef(CONFIG_POSIX_MQUEUE mqueue.c) zephyr_library_sources_ifdef(CONFIG_POSIX_SIGNAL signal.c ${STRSIGNAL_TABLE_H}) diff --git a/lib/posix/Kconfig b/lib/posix/Kconfig index 3fd013134742d5f..e99d6c40cb23732 100644 --- a/lib/posix/Kconfig +++ b/lib/posix/Kconfig @@ -54,3 +54,6 @@ source "lib/posix/Kconfig.signal" source "lib/posix/Kconfig.spinlock" source "lib/posix/Kconfig.timer" source "lib/posix/Kconfig.uname" + +# POSIX extensions to ISO C +source "lib/posix/Kconfig.cx.string" diff --git a/lib/posix/Kconfig.cx.string b/lib/posix/Kconfig.cx.string new file mode 100644 index 000000000000000..4dc5ef938fbbc14 --- /dev/null +++ b/lib/posix/Kconfig.cx.string @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Meta +# +# SPDX-License-Identifier: Apache-2.0 + +# CX: Extension to the ISO C standard +# See IEEE 1003.1-2017 + +config POSIX_CX_STRERROR_R + bool "Get error message string" + default y if POSIX_API + select COMMON_LIBC_STRERROR + help + Enable the strerror_r() POSIX C extension. + + This function is a thread-safe version of ISO C strerror(). diff --git a/lib/libc/minimal/source/string/strerror.c b/lib/posix/strerror_r.c similarity index 67% rename from lib/libc/minimal/source/string/strerror.c rename to lib/posix/strerror_r.c index 77dfd8b477ab31e..4a725d300c2157a 100644 --- a/lib/libc/minimal/source/string/strerror.c +++ b/lib/posix/strerror_r.c @@ -16,20 +16,7 @@ * const char *const sys_errlist[sys_nerr]; * const uint8_t sys_errlen[sys_nerr]; */ -#include "libc/minimal/strerror_table.h" - -/* - * See https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html - */ -char *strerror(int errnum) -{ - if (IS_ENABLED(CONFIG_MINIMAL_LIBC_STRING_ERROR_TABLE) && - errnum >= 0 && errnum < sys_nerr) { - return (char *)sys_errlist[errnum]; - } - - return (char *) ""; -} +#include "libc/common/strerror_table.h" /* * See @@ -41,7 +28,7 @@ int strerror_r(int errnum, char *strerrbuf, size_t buflen) size_t msg_len; if (errnum >= 0 && errnum < sys_nerr) { - if (IS_ENABLED(CONFIG_MINIMAL_LIBC_STRING_ERROR_TABLE)) { + if (IS_ENABLED(CONFIG_COMMON_LIBC_STRING_ERROR_TABLE)) { msg = sys_errlist[errnum]; msg_len = sys_errlen[errnum]; } else { diff --git a/scripts/build/gen_strerror_table.py b/scripts/build/gen_strerror_table.py index 7ec91df32741988..02d95bf893290f8 100755 --- a/scripts/build/gen_strerror_table.py +++ b/scripts/build/gen_strerror_table.py @@ -21,7 +21,25 @@ def front_matter(sys_nerr): #include -#define sys_nerr {sys_nerr}''' + +#define sys_nerr {sys_nerr} + +#ifndef __sys_errlist_declare + +extern const char *const sys_errlist[{sys_nerr}]; +extern const uint8_t sys_errlen[{sys_nerr}]; + +#else + +const char *const sys_errlist[{sys_nerr}]; +const uint8_t sys_errlen[{sys_nerr}]; +''' + +def end_matter(): + return f''' + +#endif /* __sys_errlist_declare */ +''' def gen_strerror_table(input, output): @@ -61,7 +79,7 @@ def gen_strerror_table(input, output): # Generate string table print( - f'static const char *const sys_errlist[sys_nerr] = {{', file=outf) + f'const char *const sys_errlist[sys_nerr] = {{', file=outf) print('[0] = "Success",', file=outf) for symbol in symbols: print(f'[{symbol}] = "{msgs[symbol]}",', file=outf) @@ -70,13 +88,15 @@ def gen_strerror_table(input, output): # Generate string lengths (includes trailing '\0') print( - f'static const uint8_t sys_errlen[sys_nerr] = {{', file=outf) + f'const uint8_t sys_errlen[sys_nerr] = {{', file=outf) print('[0] = 8,', file=outf) for symbol in symbols: print(f'[{symbol}] = {len(msgs[symbol]) + 1},', file=outf) print('};', file=outf) + print(end_matter(), file=outf) + def parse_args(): parser = argparse.ArgumentParser(allow_abbrev=False) diff --git a/scripts/ci/errno.py b/scripts/ci/errno.py index a7d0063072b066b..fb4691cb9d722d4 100755 --- a/scripts/ci/errno.py +++ b/scripts/ci/errno.py @@ -4,9 +4,9 @@ # # SPDX-License-Identifier: Apache-2.0 -"""Check minimal libc error numbers against newlib. +"""Check common libc error numbers against newlib. -This script loads the errno.h included in Zephyr's minimal libc and checks its +This script loads the errno.h included in Zephyr's common libc and checks its contents against the SDK's newlib errno.h. This is done to ensure that both C libraries are aligned at all times. """ @@ -30,20 +30,20 @@ def parse_errno(path): def main(): - minimal = Path("lib/libc/minimal/include/errno.h") + common = Path("lib/libc/common/include/errno.h") newlib = Path("arm-zephyr-eabi/arm-zephyr-eabi/include/sys/errno.h") try: - minimal = os.environ['ZEPHYR_BASE'] / minimal + common = os.environ['ZEPHYR_BASE'] / common newlib = os.environ['ZEPHYR_SDK_INSTALL_DIR'] / newlib except KeyError as e: print(f'Environment variable missing: {e}', file=sys.stderr) sys.exit(1) - minimal = parse_errno(minimal) + common = parse_errno(common) newlib = parse_errno(newlib) - for e in minimal: + for e in common: if e[0] not in [x[0] for x in newlib] or e[1] != next( filter(lambda _e: _e[0] == e[0], newlib))[1]: print('Invalid entry in errno.h:', file=sys.stderr) diff --git a/tests/lib/c_lib/common/prj.conf b/tests/lib/c_lib/common/prj.conf index 331c19559db1091..869fd338e6afd76 100644 --- a/tests/lib/c_lib/common/prj.conf +++ b/tests/lib/c_lib/common/prj.conf @@ -1,5 +1,3 @@ CONFIG_ZTEST=y CONFIG_TEST_USERSPACE=y CONFIG_ZTEST_FATAL_HOOK=y -CONFIG_MINIMAL_LIBC_NON_REENTRANT_FUNCTIONS=y -CONFIG_MINIMAL_LIBC_RAND=y diff --git a/tests/lib/c_lib/strerror/Kconfig b/tests/lib/c_lib/strerror/Kconfig deleted file mode 100644 index 4b04d89f51dbe28..000000000000000 --- a/tests/lib/c_lib/strerror/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2022 Meta - -mainmenu "Strerror test parameters" - -source "Kconfig.zephyr" - -config MINIMAL_LIBC_DISABLE_STRING_ERROR_TABLE - depends on MINIMAL_LIBC - bool - default y if !MINIMAL_LIBC_STRING_ERROR_TABLE - default n if MINIMAL_LIBC_STRING_ERROR_TABLE - help - This option is only here to simplify conditional expressions - in test_strerror.c rather than inverting logic for the - global MINIMAL_LIBC_STRING_ERROR_TABLE option. diff --git a/tests/lib/c_lib/strerror/src/main.c b/tests/lib/c_lib/strerror/src/main.c index 8bfd06bbff549c0..96539a1fa91d8a6 100644 --- a/tests/lib/c_lib/strerror/src/main.c +++ b/tests/lib/c_lib/strerror/src/main.c @@ -4,10 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifdef CONFIG_NEWLIB_LIBC -#define _POSIX_C_SOURCE 200809 -#endif - #include #include @@ -19,7 +15,7 @@ ZTEST(libc_strerror, test_strerror) const char *actual; errno = 4242; - if (IS_ENABLED(CONFIG_MINIMAL_LIBC_DISABLE_STRING_ERROR_TABLE)) { + if (!IS_ENABLED(CONFIG_COMMON_LIBC_STRING_ERROR_TABLE)) { expected = ""; actual = strerror(EINVAL); } else { @@ -47,7 +43,7 @@ ZTEST(libc_strerror, test_strerror) #endif /* consistent behaviour for "Success" */ - if (!IS_ENABLED(CONFIG_MINIMAL_LIBC_DISABLE_STRING_ERROR_TABLE)) { + if (IS_ENABLED(CONFIG_COMMON_LIBC_STRING_ERROR_TABLE)) { expected = "Success"; actual = strerror(0); zassert_equal(0, strcmp(expected, actual), @@ -55,46 +51,4 @@ ZTEST(libc_strerror, test_strerror) } } -ZTEST(libc_strerror, test_strerror_r) -{ - const char *expected; - char actual[] = {'1', 'n', 'v', 'a', '1', '1', 'd', ' ', 'a', - '2', 'g', 'u', 'm', '3', 'n', '7', 0x00, 0x42}; - static const size_t n = sizeof(actual); - - if (IS_ENABLED(CONFIG_NEWLIB_LIBC) || IS_ENABLED(CONFIG_ARCMWDT_LIBC)) { - /* FIXME: Please see Issue #46846 */ - ztest_test_skip(); - } - - errno = 4242; - if (IS_ENABLED(CONFIG_MINIMAL_LIBC_DISABLE_STRING_ERROR_TABLE)) { - expected = ""; - zassert_equal(0, strerror_r(EINVAL, actual, n), ""); - zassert_equal(0, strncmp(expected, actual, n), - "mismatch: exp: %s act: %s", expected, actual); - } else { - expected = "Invalid argument"; - zassert_equal(0, strerror_r(EINVAL, actual, n), "%d", - strerror_r(EINVAL, actual, n)); - zassert_equal(0, strncmp(expected, actual, n), - "mismatch: exp: %s act: %s", expected, actual); - /* only the necessary buffer area is written */ - zassert_equal(0x42, (uint8_t)actual[n - 1], - "exp: %02x act: %02x", 0x42, - (uint8_t)actual[n - 1]); - - zassert_equal(ERANGE, strerror_r(EINVAL, actual, 0), ""); - } - - /* do not change errno on success */ - zassert_equal(4242, errno, ""); - - errno = 0; - zassert_equal(EINVAL, strerror_r(-42, actual, n), ""); - zassert_equal(EINVAL, strerror_r(4242, actual, n), ""); - /* do not change errno on failure */ - zassert_equal(0, errno, ""); -} - ZTEST_SUITE(libc_strerror, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/lib/c_lib/strerror/testcase.yaml b/tests/lib/c_lib/strerror/testcase.yaml index 2475c3e31ecd412..176c541c51ec5eb 100644 --- a/tests/lib/c_lib/strerror/testcase.yaml +++ b/tests/lib/c_lib/strerror/testcase.yaml @@ -9,14 +9,14 @@ tests: tags: minimal_libc extra_configs: - CONFIG_MINIMAL_LIBC=y - - CONFIG_MINIMAL_LIBC_STRING_ERROR_TABLE=y + - CONFIG_COMMON_LIBC_STRING_ERROR_TABLE=y - CONFIG_MINIMAL_LIBC_NON_REENTRANT_FUNCTIONS=y libraries.libc.strerror.minimal.no_strerror_table: filter: CONFIG_MINIMAL_LIBC_SUPPORTED tags: minimal_libc extra_configs: - CONFIG_MINIMAL_LIBC=y - - CONFIG_MINIMAL_LIBC_STRING_ERROR_TABLE=n + - CONFIG_COMMON_LIBC_STRING_ERROR_TABLE=n - CONFIG_MINIMAL_LIBC_NON_REENTRANT_FUNCTIONS=y libraries.libc.strerror.newlib: filter: CONFIG_NEWLIB_LIBC_SUPPORTED diff --git a/tests/posix/cx/CMakeLists.txt b/tests/posix/cx/CMakeLists.txt new file mode 100644 index 000000000000000..9370e058c75980d --- /dev/null +++ b/tests/posix/cx/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(posix_cx) + +FILE(GLOB app_sources src/**/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/posix/cx/prj.conf b/tests/posix/cx/prj.conf new file mode 100644 index 000000000000000..6aba6f3d52cef11 --- /dev/null +++ b/tests/posix/cx/prj.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_POSIX_CX_STRERROR_R=y diff --git a/tests/posix/cx/src/string/_main.c b/tests/posix/cx/src/string/_main.c new file mode 100644 index 000000000000000..bac7f7c0881c0b4 --- /dev/null +++ b/tests/posix/cx/src/string/_main.c @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +ZTEST_SUITE(posix_cx_string, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/posix/cx/src/string/strerror_r.c b/tests/posix/cx/src/string/strerror_r.c new file mode 100644 index 000000000000000..4fea7dc42e28ff8 --- /dev/null +++ b/tests/posix/cx/src/string/strerror_r.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +ZTEST(posix_cx_string, test_strerror_r) +{ + const char *expected; + char actual[] = {'1', 'n', 'v', 'a', '1', '1', 'd', ' ', 'a', + '2', 'g', 'u', 'm', '3', 'n', '7', 0x00, 0x42}; + static const size_t n = sizeof(actual); + + errno = 4242; + if (!IS_ENABLED(CONFIG_COMMON_LIBC_STRING_ERROR_TABLE)) { + expected = ""; + zassert_equal(0, strerror_r(EINVAL, actual, n), ""); + zassert_equal(0, strncmp(expected, actual, n), "mismatch: exp: %s act: %s", + expected, actual); + } else { + expected = "Invalid argument"; + zassert_equal(0, strerror_r(EINVAL, actual, n), "%d", + strerror_r(EINVAL, actual, n)); + zassert_equal(0, strncmp(expected, actual, n), "mismatch: exp: %s act: %s", + expected, actual); + /* only the necessary buffer area is written */ + zassert_equal(0x42, (uint8_t)actual[n - 1], "exp: %02x act: %02x", 0x42, + (uint8_t)actual[n - 1]); + + zassert_equal(ERANGE, strerror_r(EINVAL, actual, 0), ""); + } + + /* do not change errno on success */ + zassert_equal(4242, errno, ""); + + errno = 0; + zassert_equal(EINVAL, strerror_r(-42, actual, n), ""); + zassert_equal(EINVAL, strerror_r(4242, actual, n), ""); + /* do not change errno on failure */ + zassert_equal(0, errno, ""); +}