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, ""); +}