From a69c04f08c941636b67d6aff72736902a8aa0f30 Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Sat, 12 Apr 2025 10:55:36 -0400 Subject: [PATCH 1/6] eventfd: bring config to top-level of posix dir, since it is not posix The eventfd configuration does not need to be so deeply nested within POSIX since it does not depend on POSIX completely. Signed-off-by: Chris Friedt --- lib/posix/CMakeLists.txt | 1 + lib/posix/Kconfig | 5 ++++- lib/posix/eventfd/CMakeLists.txt | 4 ++++ lib/posix/{options/Kconfig.compat => eventfd/Kconfig} | 4 ---- lib/posix/{options => eventfd}/eventfd.c | 0 lib/posix/options/CMakeLists.txt | 1 - lib/posix/options/Kconfig | 2 -- 7 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 lib/posix/eventfd/CMakeLists.txt rename lib/posix/{options/Kconfig.compat => eventfd/Kconfig} (87%) rename lib/posix/{options => eventfd}/eventfd.c (100%) diff --git a/lib/posix/CMakeLists.txt b/lib/posix/CMakeLists.txt index d62108b66f007..3db3541a54cb8 100644 --- a/lib/posix/CMakeLists.txt +++ b/lib/posix/CMakeLists.txt @@ -1,4 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 add_subdirectory(options) +add_subdirectory_ifdef(CONFIG_EVENTFD eventfd) add_subdirectory_ifdef(CONFIG_POSIX_SHELL shell) diff --git a/lib/posix/Kconfig b/lib/posix/Kconfig index 534baf08cd240..1cc15de555e41 100644 --- a/lib/posix/Kconfig +++ b/lib/posix/Kconfig @@ -7,4 +7,7 @@ menu "POSIX API Support" rsource "options/Kconfig" rsource "shell/Kconfig" -endmenu # "POSIX API Support" +endmenu + +# Eventfd Support (not officially POSIX) +rsource "eventfd/Kconfig" diff --git a/lib/posix/eventfd/CMakeLists.txt b/lib/posix/eventfd/CMakeLists.txt new file mode 100644 index 0000000000000..2736572dd0061 --- /dev/null +++ b/lib/posix/eventfd/CMakeLists.txt @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(eventfd.c) diff --git a/lib/posix/options/Kconfig.compat b/lib/posix/eventfd/Kconfig similarity index 87% rename from lib/posix/options/Kconfig.compat rename to lib/posix/eventfd/Kconfig index e15cc869a7be6..019daef4a3524 100644 --- a/lib/posix/options/Kconfig.compat +++ b/lib/posix/eventfd/Kconfig @@ -3,8 +3,6 @@ # # SPDX-License-Identifier: Apache-2.0 -menu "Miscellaneous POSIX-related options" - config EVENTFD bool "Support for eventfd" select ZVFS @@ -13,5 +11,3 @@ config EVENTFD Enable support for event file descriptors, eventfd. An eventfd can be used as an event wait/notify mechanism together with POSIX calls like read, write and poll. - -endmenu diff --git a/lib/posix/options/eventfd.c b/lib/posix/eventfd/eventfd.c similarity index 100% rename from lib/posix/options/eventfd.c rename to lib/posix/eventfd/eventfd.c diff --git a/lib/posix/options/CMakeLists.txt b/lib/posix/options/CMakeLists.txt index 429f1d3932eb2..3f71558e83350 100644 --- a/lib/posix/options/CMakeLists.txt +++ b/lib/posix/options/CMakeLists.txt @@ -30,7 +30,6 @@ if (NOT CONFIG_TC_PROVIDES_POSIX_SIGNALS) endif() zephyr_library() -zephyr_library_sources_ifdef(CONFIG_EVENTFD eventfd.c) if (NOT CONFIG_TC_PROVIDES_POSIX_ASYNCHRONOUS_IO) zephyr_library_sources_ifdef(CONFIG_POSIX_ASYNCHRONOUS_IO aio.c) diff --git a/lib/posix/options/Kconfig b/lib/posix/options/Kconfig index 6c2b129170e30..cc077cf9abcde 100644 --- a/lib/posix/options/Kconfig +++ b/lib/posix/options/Kconfig @@ -40,8 +40,6 @@ rsource "Kconfig.xsi_threads_ext" endmenu # "X/Open system interfaces" -rsource "Kconfig.compat" - rsource "Kconfig.toolchain" endmenu # "POSIX Options" From 093268ebdc75b4b9a1013e09284c6a501c1f8393 Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Sat, 12 Apr 2025 07:54:36 -0400 Subject: [PATCH 2/6] posix: separate option groups into c library ext and system interfaces Separate the POSIX implementation into two categories: - Extensions to ISO C - System Interfaces The first category include standalone functions that generally do not require OS support or depend on any other features within the POSIX specification. The Option Groups that comprise this category include - POSIX_C_LIB_EXT: e.g. strnlen(), fnmatch() - POSIX_C_LANG_SUPPORT_R: e.g. gmtime_r(), strtok_r() The second category includes the majority of other POSIX Option Groups that do require OS support. The latter group may also be categorized generally as being NATIVE_LIBC_INCOMPATIBLE, although that might eventually become more granular. Signed-off-by: Chris Friedt --- lib/posix/CMakeLists.txt | 4 ++- lib/posix/Kconfig | 31 +++++++++++++++++++ lib/posix/{options => }/Kconfig.profile | 26 +++++++++------- lib/posix/{options => }/Kconfig.toolchain | 0 lib/posix/c_lang_support_r/CMakeLists.txt | 8 +++++ .../Kconfig} | 0 lib/posix/c_lib_ext/CMakeLists.txt | 17 ++++++++++ .../Kconfig.c_lib_ext => c_lib_ext/Kconfig} | 0 lib/posix/{options => c_lib_ext}/fnmatch.c | 0 lib/posix/{options => c_lib_ext}/getentropy.c | 0 .../{options => c_lib_ext}/getopt/README | 0 .../{options => c_lib_ext}/getopt/getopt.c | 0 .../{options => c_lib_ext}/getopt/getopt.h | 0 .../getopt/getopt_common.c | 0 .../getopt/getopt_common.h | 0 .../getopt/getopt_long.c | 0 lib/posix/options/CMakeLists.txt | 18 +---------- lib/posix/options/Kconfig | 10 ------ tests/posix/single_process/prj.conf | 1 + 19 files changed, 75 insertions(+), 40 deletions(-) rename lib/posix/{options => }/Kconfig.profile (93%) rename lib/posix/{options => }/Kconfig.toolchain (100%) create mode 100644 lib/posix/c_lang_support_r/CMakeLists.txt rename lib/posix/{options/Kconfig.c_lang_r => c_lang_support_r/Kconfig} (100%) create mode 100644 lib/posix/c_lib_ext/CMakeLists.txt rename lib/posix/{options/Kconfig.c_lib_ext => c_lib_ext/Kconfig} (100%) rename lib/posix/{options => c_lib_ext}/fnmatch.c (100%) rename lib/posix/{options => c_lib_ext}/getentropy.c (100%) rename lib/posix/{options => c_lib_ext}/getopt/README (100%) rename lib/posix/{options => c_lib_ext}/getopt/getopt.c (100%) rename lib/posix/{options => c_lib_ext}/getopt/getopt.h (100%) rename lib/posix/{options => c_lib_ext}/getopt/getopt_common.c (100%) rename lib/posix/{options => c_lib_ext}/getopt/getopt_common.h (100%) rename lib/posix/{options => c_lib_ext}/getopt/getopt_long.c (100%) diff --git a/lib/posix/CMakeLists.txt b/lib/posix/CMakeLists.txt index 3db3541a54cb8..49d260f0a9bd3 100644 --- a/lib/posix/CMakeLists.txt +++ b/lib/posix/CMakeLists.txt @@ -1,5 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 -add_subdirectory(options) add_subdirectory_ifdef(CONFIG_EVENTFD eventfd) +add_subdirectory_ifdef(CONFIG_POSIX_C_LANG_SUPPORT_R c_lang_support_r) +add_subdirectory_ifdef(CONFIG_POSIX_C_LIB_EXT c_lib_ext) add_subdirectory_ifdef(CONFIG_POSIX_SHELL shell) +add_subdirectory_ifdef(CONFIG_POSIX_SYSTEM_INTERFACES options) diff --git a/lib/posix/Kconfig b/lib/posix/Kconfig index 1cc15de555e41..067def5180df0 100644 --- a/lib/posix/Kconfig +++ b/lib/posix/Kconfig @@ -1,11 +1,42 @@ # Copyright (c) 2024 Meta +# Copyright (c) 2025 Tenstorrent AI ULC # # SPDX-License-Identifier: Apache-2.0 menu "POSIX API Support" +# POSIX Subprofile Definitions +rsource "Kconfig.profile" + +# Toolchain hooks for external implementations +rsource "Kconfig.toolchain" + +# POSIX C Library Extensions +# This menu is for POSIX Option Groups that do not require OS support. +menu "POSIX C Library Extensions" +rsource "c_lang_support_r/Kconfig" +rsource "c_lib_ext/Kconfig" +endmenu + +# POSIX System Interfaces +menuconfig POSIX_SYSTEM_INTERFACES + bool "POSIX System Interfaces" + select NATIVE_LIBC_INCOMPATIBLE + help + Select 'y' here to support POSIX System Interfaces within Zephyr. + + Options in this menu are organized by POSIX subprofiling Option Group. + + For more information, see + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + + +if POSIX_SYSTEM_INTERFACES rsource "options/Kconfig" + +# POSIX Shell utilities rsource "shell/Kconfig" +endif endmenu diff --git a/lib/posix/options/Kconfig.profile b/lib/posix/Kconfig.profile similarity index 93% rename from lib/posix/options/Kconfig.profile rename to lib/posix/Kconfig.profile index a3b0a4f94e531..c1e2e0724c06a 100644 --- a/lib/posix/options/Kconfig.profile +++ b/lib/posix/Kconfig.profile @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -config POSIX_SYSTEM_HEADERS +config POSIX_SYSTEM_INTERFACES bool select NATIVE_LIBC_INCOMPATIBLE help @@ -10,8 +10,7 @@ config POSIX_SYSTEM_HEADERS config POSIX_API bool "POSIX APIs" - select NATIVE_LIBC_INCOMPATIBLE - select POSIX_SYSTEM_HEADERS + select POSIX_SYSTEM_INTERFACES select POSIX_BASE_DEFINITIONS # clock_gettime(), pthread_create(), sem_get(), etc select POSIX_AEP_REALTIME_MINIMAL # CLOCK_MONOTONIC, pthread_attr_setstack(), etc select POSIX_NETWORKING if NETWORKING # inet_ntoa(), socket(), etc @@ -38,13 +37,13 @@ choice POSIX_AEP_CHOICE https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html config POSIX_AEP_CHOICE_NONE - bool "No pre-defined POSIX subprofile" + bool "No POSIX subprofile" help - No pre-defined POSIX profile is selected. + No POSIX subprofile is selected. config POSIX_AEP_CHOICE_BASE - bool "Base definitions (system interfaces)" - select NATIVE_LIBC_INCOMPATIBLE + bool "Minimal POSIX System Profile" + select POSIX_SYSTEM_INTERFACES select POSIX_BASE_DEFINITIONS help Only enable the base definitions required for all POSIX systems. @@ -54,7 +53,7 @@ config POSIX_AEP_CHOICE_BASE config POSIX_AEP_CHOICE_PSE51 bool "Minimal Realtime System Profile (PSE51)" - select NATIVE_LIBC_INCOMPATIBLE + select POSIX_SYSTEM_INTERFACES select POSIX_BASE_DEFINITIONS select POSIX_AEP_REALTIME_MINIMAL help @@ -67,7 +66,7 @@ config POSIX_AEP_CHOICE_PSE51 config POSIX_AEP_CHOICE_PSE52 bool "Realtime Controller System Profile (PSE52)" - select NATIVE_LIBC_INCOMPATIBLE + select POSIX_SYSTEM_INTERFACES select POSIX_BASE_DEFINITIONS select POSIX_AEP_REALTIME_MINIMAL select POSIX_AEP_REALTIME_CONTROLLER @@ -81,7 +80,7 @@ config POSIX_AEP_CHOICE_PSE52 config POSIX_AEP_CHOICE_PSE53 bool "Dedicated Realtime System Profile (PSE53)" - select NATIVE_LIBC_INCOMPATIBLE + select POSIX_SYSTEM_INTERFACES select POSIX_BASE_DEFINITIONS select POSIX_AEP_REALTIME_MINIMAL select POSIX_AEP_REALTIME_CONTROLLER @@ -98,10 +97,11 @@ config POSIX_AEP_CHOICE_PSE53 endchoice # POSIX_AEP_CHOICE -# Base Definitions (System Interfaces) +if POSIX_SYSTEM_INTERFACES + +# Mandatory POSIX System Interfaces (base profile) config POSIX_BASE_DEFINITIONS bool - select POSIX_SYSTEM_HEADERS select POSIX_ASYNCHRONOUS_IO select POSIX_BARRIERS select POSIX_CLOCK_SELECTION @@ -187,3 +187,5 @@ config POSIX_AEP_REALTIME_DEDICATED For more information, please see https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + +endif # POSIX_SYSTEM_INTERFACE diff --git a/lib/posix/options/Kconfig.toolchain b/lib/posix/Kconfig.toolchain similarity index 100% rename from lib/posix/options/Kconfig.toolchain rename to lib/posix/Kconfig.toolchain diff --git a/lib/posix/c_lang_support_r/CMakeLists.txt b/lib/posix/c_lang_support_r/CMakeLists.txt new file mode 100644 index 0000000000000..db1e5c8d3a917 --- /dev/null +++ b/lib/posix/c_lang_support_r/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright The Zephyr Project Contributors +# SPDX-License-Identifier: Apache-2.0 + +set(POSIX_VERSION 200809L) + +if (CONFIG_POSIX_C_LANG_SUPPORT_R) + zephyr_compile_definitions(-D_POSIX_THREAD_SAFE_FUNCTIONS=${POSIX_VERSION}) +endif() diff --git a/lib/posix/options/Kconfig.c_lang_r b/lib/posix/c_lang_support_r/Kconfig similarity index 100% rename from lib/posix/options/Kconfig.c_lang_r rename to lib/posix/c_lang_support_r/Kconfig diff --git a/lib/posix/c_lib_ext/CMakeLists.txt b/lib/posix/c_lib_ext/CMakeLists.txt new file mode 100644 index 0000000000000..a4c3e09d839f2 --- /dev/null +++ b/lib/posix/c_lib_ext/CMakeLists.txt @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(getopt) + +if (CONFIG_TC_PROVIDES_POSIX_C_LIB_EXT) + return() +endif() + +zephyr_library() +zephyr_library_sources( + fnmatch.c + getentropy.c + getopt/getopt.c + getopt/getopt_common.c +) + +zephyr_library_sources_ifdef(CONFIG_GETOPT_LONG getopt/getopt_long.c) diff --git a/lib/posix/options/Kconfig.c_lib_ext b/lib/posix/c_lib_ext/Kconfig similarity index 100% rename from lib/posix/options/Kconfig.c_lib_ext rename to lib/posix/c_lib_ext/Kconfig diff --git a/lib/posix/options/fnmatch.c b/lib/posix/c_lib_ext/fnmatch.c similarity index 100% rename from lib/posix/options/fnmatch.c rename to lib/posix/c_lib_ext/fnmatch.c diff --git a/lib/posix/options/getentropy.c b/lib/posix/c_lib_ext/getentropy.c similarity index 100% rename from lib/posix/options/getentropy.c rename to lib/posix/c_lib_ext/getentropy.c diff --git a/lib/posix/options/getopt/README b/lib/posix/c_lib_ext/getopt/README similarity index 100% rename from lib/posix/options/getopt/README rename to lib/posix/c_lib_ext/getopt/README diff --git a/lib/posix/options/getopt/getopt.c b/lib/posix/c_lib_ext/getopt/getopt.c similarity index 100% rename from lib/posix/options/getopt/getopt.c rename to lib/posix/c_lib_ext/getopt/getopt.c diff --git a/lib/posix/options/getopt/getopt.h b/lib/posix/c_lib_ext/getopt/getopt.h similarity index 100% rename from lib/posix/options/getopt/getopt.h rename to lib/posix/c_lib_ext/getopt/getopt.h diff --git a/lib/posix/options/getopt/getopt_common.c b/lib/posix/c_lib_ext/getopt/getopt_common.c similarity index 100% rename from lib/posix/options/getopt/getopt_common.c rename to lib/posix/c_lib_ext/getopt/getopt_common.c diff --git a/lib/posix/options/getopt/getopt_common.h b/lib/posix/c_lib_ext/getopt/getopt_common.h similarity index 100% rename from lib/posix/options/getopt/getopt_common.h rename to lib/posix/c_lib_ext/getopt/getopt_common.h diff --git a/lib/posix/options/getopt/getopt_long.c b/lib/posix/c_lib_ext/getopt/getopt_long.c similarity index 100% rename from lib/posix/options/getopt/getopt_long.c rename to lib/posix/c_lib_ext/getopt/getopt_long.c diff --git a/lib/posix/options/CMakeLists.txt b/lib/posix/options/CMakeLists.txt index 3f71558e83350..3d082a3418be9 100644 --- a/lib/posix/options/CMakeLists.txt +++ b/lib/posix/options/CMakeLists.txt @@ -9,7 +9,7 @@ zephyr_syscall_header_ifdef(CONFIG_POSIX_CLOCK_SELECTION posix_clock.h) zephyr_syscall_header_ifdef(CONFIG_POSIX_TIMERS posix_clock.h) zephyr_syscall_header_ifdef(CONFIG_XSI_SINGLE_PROCESS posix_clock.h) -if(CONFIG_POSIX_SYSTEM_HEADERS) +if(CONFIG_POSIX_SYSTEM_INTERFACES) zephyr_include_directories(${ZEPHYR_BASE}/include/zephyr/posix) endif() @@ -46,15 +46,6 @@ if (CONFIG_POSIX_CLOCK_SELECTION) zephyr_compile_definitions(-D_POSIX_CLOCK_SELECTION=${POSIX_VERSION}) endif() -if (NOT CONFIG_TC_PROVIDES_POSIX_C_LIB_EXT) - zephyr_library_sources_ifdef(CONFIG_POSIX_C_LIB_EXT - fnmatch.c - getentropy.c - getopt/getopt.c - getopt/getopt_common.c - ) -endif() - if (NOT CONFIG_TC_PROVIDES_POSIX_DEVICE_IO) zephyr_library_sources_ifdef(CONFIG_POSIX_DEVICE_IO # perror should be moved to the common libc @@ -184,13 +175,6 @@ if (NOT CONFIG_TC_PROVIDES_XSI_SYSTEM_LOGGING) zephyr_library_sources_ifdef(CONFIG_XSI_SYSTEM_LOGGING syslog.c) endif() -zephyr_library_sources_ifdef(CONFIG_GETOPT_LONG - getopt/getopt_long.c -) -zephyr_include_directories_ifdef(CONFIG_POSIX_C_LIB_EXT - getopt/ -) - zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include ${ARCH_DIR}/${ARCH}/include diff --git a/lib/posix/options/Kconfig b/lib/posix/options/Kconfig index cc077cf9abcde..d635e07b23dba 100644 --- a/lib/posix/options/Kconfig +++ b/lib/posix/options/Kconfig @@ -4,14 +4,8 @@ # # SPDX-License-Identifier: Apache-2.0 -menu "POSIX Options" - -rsource "Kconfig.profile" - rsource "Kconfig.aio" rsource "Kconfig.barrier" -rsource "Kconfig.c_lang_r" -rsource "Kconfig.c_lib_ext" rsource "Kconfig.device_io" rsource "Kconfig.fd_mgmt" rsource "Kconfig.file_system_r" @@ -39,7 +33,3 @@ rsource "Kconfig.xsi_system_logging" rsource "Kconfig.xsi_threads_ext" endmenu # "X/Open system interfaces" - -rsource "Kconfig.toolchain" - -endmenu # "POSIX Options" diff --git a/tests/posix/single_process/prj.conf b/tests/posix/single_process/prj.conf index 7422432b9d0b8..ceec42c12c048 100644 --- a/tests/posix/single_process/prj.conf +++ b/tests/posix/single_process/prj.conf @@ -1,4 +1,5 @@ CONFIG_ZTEST=y +CONFIG_POSIX_SYSTEM_INTERFACES=y CONFIG_POSIX_SINGLE_PROCESS=y # Let's explicitly choose PICOLIBC, so it is used if supported even if it would not have been the From 8162bd0aa2b653c615b1dfff404696aa1aa59827 Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Sun, 31 Aug 2025 10:15:09 -0400 Subject: [PATCH 3/6] posix: c_lib_ext: apply clang-format to getopt sources The getopt sources were not formatted according to our codying style conventions, so apply formatting rules as a separate commit. Signed-off-by: Chris Friedt --- lib/posix/c_lib_ext/getopt/getopt.c | 13 +- lib/posix/c_lib_ext/getopt/getopt.h | 30 ++-- lib/posix/c_lib_ext/getopt/getopt_common.c | 12 +- lib/posix/c_lib_ext/getopt/getopt_long.c | 172 +++++++++------------ 4 files changed, 99 insertions(+), 128 deletions(-) diff --git a/lib/posix/c_lib_ext/getopt/getopt.c b/lib/posix/c_lib_ext/getopt/getopt.c index c34e7fd7dccdf..a81e0ca279a2d 100644 --- a/lib/posix/c_lib_ext/getopt/getopt.c +++ b/lib/posix/c_lib_ext/getopt/getopt.c @@ -41,9 +41,9 @@ #include LOG_MODULE_REGISTER(getopt); -#define BADCH ((int)'?') -#define BADARG ((int)':') -#define EMSG "" +#define BADCH ((int)'?') +#define BADARG ((int)':') +#define EMSG "" void getopt_init(void) { @@ -61,7 +61,7 @@ void getopt_init(void) #if CONFIG_GETOPT_LONG state->nonopt_start = -1; /* first non option argument (for permute) */ - state->nonopt_end = -1; /* first option after non options (for permute) */ + state->nonopt_end = -1; /* first option after non options (for permute) */ #endif opterr = 1; @@ -151,8 +151,7 @@ int getopt(int nargc, char *const nargv[], const char *ostr) return BADARG; } if (state->opterr) { - LOG_DBG("option requires an argument -- %c", - state->optopt); + LOG_DBG("option requires an argument -- %c", state->optopt); } z_getopt_global_state_update(state); return BADCH; @@ -161,5 +160,5 @@ int getopt(int nargc, char *const nargv[], const char *ostr) ++state->optind; } z_getopt_global_state_update(state); - return state->optopt; /* return option letter */ + return state->optopt; /* return option letter */ } diff --git a/lib/posix/c_lib_ext/getopt/getopt.h b/lib/posix/c_lib_ext/getopt/getopt.h index 666c5541c635c..eb0641f6c9045 100644 --- a/lib/posix/c_lib_ext/getopt/getopt.h +++ b/lib/posix/c_lib_ext/getopt/getopt.h @@ -14,13 +14,13 @@ extern "C" { #include struct getopt_state { - int opterr; /* if error message should be printed */ - int optind; /* index into parent argv vector */ - int optopt; /* character checked for validity */ - int optreset; /* reset getopt */ - char *optarg; /* argument associated with option */ + int opterr; /* if error message should be printed */ + int optind; /* index into parent argv vector */ + int optopt; /* character checked for validity */ + int optreset; /* reset getopt */ + char *optarg; /* argument associated with option */ - char *place; /* option letter processing */ + char *place; /* option letter processing */ #if CONFIG_GETOPT_LONG int nonopt_start; @@ -28,15 +28,15 @@ struct getopt_state { #endif }; -extern int optreset; /* reset getopt */ +extern int optreset; /* reset getopt */ extern char *optarg; extern int opterr; extern int optind; extern int optopt; -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 struct option { /* name of long option */ @@ -79,9 +79,8 @@ struct getopt_state *getopt_state_get(void); * @return If an option was successfully found, function returns * the option character. */ -int getopt_long(int nargc, char *const *nargv, - const char *options, const struct option *long_options, - int *idx); +int getopt_long(int nargc, char *const *nargv, const char *options, + const struct option *long_options, int *idx); /** * @brief Parses the command-line arguments. @@ -106,9 +105,8 @@ int getopt_long(int nargc, char *const *nargv, * @return If an option was successfully found, function returns * the option character. */ -int getopt_long_only(int nargc, char *const *nargv, - const char *options, const struct option *long_options, - int *idx); +int getopt_long_only(int nargc, char *const *nargv, const char *options, + const struct option *long_options, int *idx); #ifdef __cplusplus } diff --git a/lib/posix/c_lib_ext/getopt/getopt_common.c b/lib/posix/c_lib_ext/getopt/getopt_common.c index f31915fdfbff4..2599d2c2d98bd 100644 --- a/lib/posix/c_lib_ext/getopt/getopt_common.c +++ b/lib/posix/c_lib_ext/getopt/getopt_common.c @@ -16,11 +16,11 @@ * When more threads are using getopt please call getopt_state_get to know * getopt state for the current thread. */ -int opterr = 1; /* if error message should be printed */ -int optind = 1; /* index into parent argv vector */ -int optopt; /* character checked for validity */ -int optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt; /* character checked for validity */ +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ /* Common state for all threads that did not have own getopt state. */ static struct getopt_state m_getopt_common_state = { @@ -34,7 +34,7 @@ static struct getopt_state m_getopt_common_state = { #if CONFIG_GETOPT_LONG .nonopt_start = -1, /* first non option argument (for permute) */ - .nonopt_end = -1, /* first option after non options (for permute) */ + .nonopt_end = -1, /* first option after non options (for permute) */ #endif }; diff --git a/lib/posix/c_lib_ext/getopt/getopt_long.c b/lib/posix/c_lib_ext/getopt/getopt_long.c index bb77a1f0ea818..e39a13b3bbcf5 100644 --- a/lib/posix/c_lib_ext/getopt/getopt_long.c +++ b/lib/posix/c_lib_ext/getopt/getopt_long.c @@ -56,33 +56,32 @@ #include LOG_MODULE_DECLARE(getopt); -#define GNU_COMPATIBLE /* Be more compatible, configure's use us! */ +#define GNU_COMPATIBLE /* Be more compatible, configure's use us! */ -#define PRINT_ERROR ((state->opterr) && (*options != ':')) +#define PRINT_ERROR ((state->opterr) && (*options != ':')) -#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ -#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ -#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ /* return values */ -#define BADCH (int)'?' -#define BADARG ((*options == ':') ? (int)':' : (int)'?') -#define INORDER 1 +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER 1 -#define EMSG "" +#define EMSG "" #ifdef GNU_COMPATIBLE -#define NO_PREFIX (-1) -#define D_PREFIX 0 -#define DD_PREFIX 1 -#define W_PREFIX 2 +#define NO_PREFIX (-1) +#define D_PREFIX 0 +#define DD_PREFIX 1 +#define W_PREFIX 2 #endif -static int getopt_internal(struct getopt_state *, int, char * const *, - const char *, const struct option *, int *, int); -static int parse_long_options(struct getopt_state *, char * const *, - const char *, const struct option *, int *, int, - int); +static int getopt_internal(struct getopt_state *, int, char *const *, const char *, + const struct option *, int *, int); +static int parse_long_options(struct getopt_state *, char *const *, const char *, + const struct option *, int *, int, int); static int gcd(int, int); static void permute_args(int, int, int, char *const *); @@ -94,21 +93,20 @@ static int dash_prefix = NO_PREFIX; #define GNUOPTCHAR "invalid option -- %c" #define RECARGSTRING "option `%s%s' requires an argument" -#define AMBIG "option `%s%.*s' is ambiguous" -#define NOARG "option `%s%.*s' doesn't allow an argument" +#define AMBIG "option `%s%.*s' is ambiguous" +#define NOARG "option `%s%.*s' doesn't allow an argument" #define ILLOPTSTRING "unrecognized option `%s%s'" #else #define RECARGSTRING "option requires an argument -- %s" -#define AMBIG "ambiguous option -- %.*s" -#define NOARG "option doesn't take an argument -- %.*s" +#define AMBIG "ambiguous option -- %.*s" +#define NOARG "option doesn't take an argument -- %.*s" #define ILLOPTSTRING "unknown option -- %s" #endif /* * Compute the greatest common divisor of a and b. */ -static int -gcd(int a, int b) +static int gcd(int a, int b) { int c; @@ -127,9 +125,7 @@ gcd(int a, int b) * from nonopt_end to opt_end (keeping the same order of arguments * in each block). */ -static void -permute_args(int panonopt_start, int panonopt_end, int opt_end, - char * const *nargv) +static void permute_args(int panonopt_start, int panonopt_end, int opt_end, char *const *nargv) { int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; char *swap; @@ -143,7 +139,7 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, cyclelen = (opt_end - panonopt_start) / ncycle; for (i = 0; i < ncycle; i++) { - cstart = panonopt_end+i; + cstart = panonopt_end + i; pos = cstart; for (j = 0; j < cyclelen; j++) { if (pos >= panonopt_end) { @@ -153,7 +149,7 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, } swap = nargv[pos]; /* LINTED const cast */ - ((char **) nargv)[pos] = nargv[cstart]; + ((char **)nargv)[pos] = nargv[cstart]; /* LINTED const cast */ ((char **)nargv)[cstart] = swap; } @@ -165,10 +161,8 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, * Parse long options in argc/argv argument vector. * Returns -1 if short_too is set and the option does not match long_options. */ -static int -parse_long_options(struct getopt_state *state, char * const *nargv, - const char *options, const struct option *long_options, - int *idx, int short_too, int flags) +static int parse_long_options(struct getopt_state *state, char *const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too, int flags) { char *current_argv, *has_equal; #ifdef GNU_COMPATIBLE @@ -244,24 +238,21 @@ parse_long_options(struct getopt_state *state, char * const *nargv, if (PRINT_ERROR) { LOG_WRN(AMBIG, #ifdef GNU_COMPATIBLE - current_dash, + current_dash, #endif - (int)current_argv_len, - current_argv); + (int)current_argv_len, current_argv); } state->optopt = 0; return BADCH; } - if (match != -1) { /* option found */ - if (long_options[match].has_arg == no_argument - && has_equal) { + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument && has_equal) { if (PRINT_ERROR) { LOG_WRN(NOARG, #ifdef GNU_COMPATIBLE - current_dash, + current_dash, #endif - (int)current_argv_len, - current_argv); + (int)current_argv_len, current_argv); } /* * XXX: GNU sets optopt to val regardless of flag @@ -288,8 +279,7 @@ parse_long_options(struct getopt_state *state, char * const *nargv, state->optarg = nargv[state->optind++]; } } - if ((long_options[match].has_arg == required_argument) - && (state->optarg == NULL)) { + if ((long_options[match].has_arg == required_argument) && (state->optarg == NULL)) { /* * Missing argument; leading ':' indicates no error * should be generated. @@ -297,9 +287,9 @@ parse_long_options(struct getopt_state *state, char * const *nargv, if (PRINT_ERROR) { LOG_WRN(RECARGSTRING, #ifdef GNU_COMPATIBLE - current_dash, + current_dash, #endif - current_argv); + current_argv); } /* * XXX: GNU sets optopt to val regardless of flag @@ -312,7 +302,7 @@ parse_long_options(struct getopt_state *state, char * const *nargv, --state->optind; return BADARG; } - } else { /* unknown option */ + } else { /* unknown option */ if (short_too) { --state->optind; return -1; @@ -320,9 +310,9 @@ parse_long_options(struct getopt_state *state, char * const *nargv, if (PRINT_ERROR) { LOG_WRN(ILLOPTSTRING, #ifdef GNU_COMPATIBLE - current_dash, + current_dash, #endif - current_argv); + current_argv); } state->optopt = 0; return BADCH; @@ -342,12 +332,11 @@ parse_long_options(struct getopt_state *state, char * const *nargv, * getopt_internal -- * Parse argc/argv argument vector. Called by user level routines. */ -static int -getopt_internal(struct getopt_state *state, int nargc, char * const *nargv, - const char *options, const struct option *long_options, - int *idx, int flags) +static int getopt_internal(struct getopt_state *state, int nargc, char *const *nargv, + const char *options, const struct option *long_options, int *idx, + int flags) { - char *oli; /* option letter list index */ + char *oli; /* option letter list index */ int optchar, short_too; if (options == NULL) { @@ -387,17 +376,15 @@ getopt_internal(struct getopt_state *state, int nargc, char * const *nargv, state->nonopt_start = state->nonopt_end = -1; } start: - if (state->optreset || !*(state->place)) {/* update scanning pointer */ + if (state->optreset || !*(state->place)) { /* update scanning pointer */ state->optreset = 0; - if (state->optind >= nargc) { /* end of argument vector */ + if (state->optind >= nargc) { /* end of argument vector */ state->place = EMSG; if (state->nonopt_end != -1) { /* do permutation, if we have to */ - permute_args(state->nonopt_start, - state->nonopt_end, - state->optind, nargv); - state->optind -= state->nonopt_end - - state->nonopt_start; + permute_args(state->nonopt_start, state->nonopt_end, state->optind, + nargv); + state->optind -= state->nonopt_end - state->nonopt_start; } else if (state->nonopt_start != -1) { /* * If we skipped non-options, set optind @@ -415,7 +402,7 @@ getopt_internal(struct getopt_state *state, int nargc, char * const *nargv, #else (state->place[1] == '\0' && strchr(options, '-') == NULL)) { #endif - state->place = EMSG; /* found non-option */ + state->place = EMSG; /* found non-option */ if (flags & FLAG_ALLARGS) { /* * GNU extension: @@ -435,12 +422,10 @@ getopt_internal(struct getopt_state *state, int nargc, char * const *nargv, if (state->nonopt_start == -1) { state->nonopt_start = state->optind; } else if (state->nonopt_end != -1) { - permute_args(state->nonopt_start, - state->nonopt_end, - state->optind, + permute_args(state->nonopt_start, state->nonopt_end, state->optind, nargv); - state->nonopt_start = state->optind - - (state->nonopt_end - state->nonopt_start); + state->nonopt_start = + state->optind - (state->nonopt_end - state->nonopt_start); state->nonopt_end = -1; } state->optind++; @@ -463,12 +448,9 @@ getopt_internal(struct getopt_state *state, int nargc, char * const *nargv, * non-options, we have to permute. */ if (state->nonopt_end != -1) { - permute_args(state->nonopt_start, - state->nonopt_end, - state->optind, + permute_args(state->nonopt_start, state->nonopt_end, state->optind, nargv); - state->optind -= state->nonopt_end - - state->nonopt_start; + state->optind -= state->nonopt_end - state->nonopt_start; } state->nonopt_start = state->nonopt_end = -1; return -1; @@ -488,16 +470,15 @@ getopt_internal(struct getopt_state *state, int nargc, char * const *nargv, dash_prefix = D_PREFIX; #endif if (*(state->place) == '-') { - state->place++; /* --foo long option */ + state->place++; /* --foo long option */ #ifdef GNU_COMPATIBLE dash_prefix = DD_PREFIX; #endif } else if (*(state->place) != ':' && strchr(options, *(state->place)) != NULL) { - short_too = 1; /* could be short option too */ + short_too = 1; /* could be short option too */ } - optchar = parse_long_options(state, nargv, options, - long_options, idx, short_too, + optchar = parse_long_options(state, nargv, options, long_options, idx, short_too, flags); if (optchar != -1) { state->place = EMSG; @@ -506,8 +487,7 @@ getopt_internal(struct getopt_state *state, int nargc, char * const *nargv, } optchar = (int)*(state->place)++; oli = strchr(options, optchar); - if (optchar == (int)':' || - (optchar == (int)'-' && *(state->place) != '\0') || + if (optchar == (int)':' || (optchar == (int)'-' && *(state->place) != '\0') || oli == NULL) { /* * If the user specified "-" and '-' isn't listed in @@ -534,9 +514,9 @@ getopt_internal(struct getopt_state *state, int nargc, char * const *nargv, } if (long_options != NULL && optchar == 'W' && oli[1] == ';') { /* -W long-option */ - if (*(state->place)) { /* no space */ - ; /* NOTHING */ - } else if (++(state->optind) >= nargc) { /* no arg */ + if (*(state->place)) { /* no space */ + ; /* NOTHING */ + } else if (++(state->optind) >= nargc) { /* no arg */ state->place = EMSG; if (PRINT_ERROR) { LOG_WRN(RECARGCHAR, optchar); @@ -549,21 +529,20 @@ getopt_internal(struct getopt_state *state, int nargc, char * const *nargv, #ifdef GNU_COMPATIBLE dash_prefix = W_PREFIX; #endif - optchar = parse_long_options(state, nargv, options, - long_options, idx, 0, flags); + optchar = parse_long_options(state, nargv, options, long_options, idx, 0, flags); state->place = EMSG; return optchar; } - if (*++oli != ':') { /* doesn't take argument */ + if (*++oli != ':') { /* doesn't take argument */ if (!*(state->place)) { ++state->optind; } - } else { /* takes (optional) argument */ + } else { /* takes (optional) argument */ state->optarg = NULL; - if (*(state->place)) { /* no white space */ + if (*(state->place)) { /* no white space */ state->optarg = state->place; - } else if (oli[1] != ':') { /* arg not optional */ - if (++state->optind >= nargc) { /* no arg */ + } else if (oli[1] != ':') { /* arg not optional */ + if (++state->optind >= nargc) { /* no arg */ state->place = EMSG; if (PRINT_ERROR) { LOG_WRN(RECARGCHAR, optchar); @@ -584,10 +563,8 @@ getopt_internal(struct getopt_state *state, int nargc, char * const *nargv, * getopt_long -- * Parse argc/argv argument vector. */ -int -getopt_long(int nargc, char *const *nargv, - const char *options, const struct option *long_options, - int *idx) +int getopt_long(int nargc, char *const *nargv, const char *options, + const struct option *long_options, int *idx) { struct getopt_state *state; int ret; @@ -595,8 +572,7 @@ getopt_long(int nargc, char *const *nargv, /* Get state of the current thread */ state = getopt_state_get(); - ret = getopt_internal(state, nargc, nargv, options, long_options, idx, - FLAG_PERMUTE); + ret = getopt_internal(state, nargc, nargv, options, long_options, idx, FLAG_PERMUTE); z_getopt_global_state_update(state); @@ -607,10 +583,8 @@ getopt_long(int nargc, char *const *nargv, * getopt_long_only -- * Parse argc/argv argument vector. */ -int -getopt_long_only(int nargc, char *const *nargv, - const char *options, const struct option *long_options, - int *idx) +int getopt_long_only(int nargc, char *const *nargv, const char *options, + const struct option *long_options, int *idx) { struct getopt_state *state; int ret; @@ -619,7 +593,7 @@ getopt_long_only(int nargc, char *const *nargv, state = getopt_state_get(); ret = getopt_internal(state, nargc, nargv, options, long_options, idx, - FLAG_PERMUTE|FLAG_LONGONLY); + FLAG_PERMUTE | FLAG_LONGONLY); z_getopt_global_state_update(state); From 9d8610bbf6fa7ab01819657897d302ce0325d1f5 Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Sat, 12 Apr 2025 06:31:16 -0400 Subject: [PATCH 4/6] posix: profiles: add custom Zephyr POSIX subprofile Add a custom Zephyr POSIX subprofile specifically for enabling the default features that Zephyr requires as per the coding guidelines. Signed-off-by: Chris Friedt --- lib/posix/Kconfig.profile | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/posix/Kconfig.profile b/lib/posix/Kconfig.profile index c1e2e0724c06a..ee1a225cf6287 100644 --- a/lib/posix/Kconfig.profile +++ b/lib/posix/Kconfig.profile @@ -41,6 +41,28 @@ config POSIX_AEP_CHOICE_NONE help No POSIX subprofile is selected. +config POSIX_AEP_CHOICE_ZEPHYR + bool "Minimal Zephyr System Profile" + select POSIX_C_LIB_EXT + select POSIX_C_LANG_SUPPORT_R + help + Zephyr expects certain POSIX functions to be available throughout the build environment, + such as gmtime_r(), strnlen(), strtok_r(), and possibly others. + + These functions are divided into two standalone Option Groups that may be enabled + independently of the remainder of the POSIX API implementation; namely POSIX_C_LIB_EXT and + POSIX_C_LANG_SUPPORT_R. If not referenced by the Zephyr kernel or application, there are no + resource implications for enabling these option groups. + + Unlike pre-defined, standard POSIX subprofiles, this subprofile is custom to Zephyr and + therefore does not need to include the base definitions or system interfaces that would + otherwise be required for a conformant POSIX system or subprofile. This system profile + does not itself meet the requirements for POSIX implementation conformance. + + For more information, see + https://docs.zephyrproject.org/latest/contribute/coding_guidelines/index.html + https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html + config POSIX_AEP_CHOICE_BASE bool "Minimal POSIX System Profile" select POSIX_SYSTEM_INTERFACES From b06f459c2350d86044a7e85972e5c4ef9ee42cad Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Sat, 12 Apr 2025 08:13:52 -0400 Subject: [PATCH 5/6] posix: profiles: make POSIX_AEP_CHOICE_ZEPHYR the default Default POSIX_AEP_CHOICE to POSIX_AEP_CHOICE_ZEPHYR Signed-off-by: Chris Friedt --- lib/posix/Kconfig.profile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/posix/Kconfig.profile b/lib/posix/Kconfig.profile index ee1a225cf6287..39d4ea2a6ee8e 100644 --- a/lib/posix/Kconfig.profile +++ b/lib/posix/Kconfig.profile @@ -26,7 +26,7 @@ config POSIX_API choice POSIX_AEP_CHOICE prompt "POSIX Subprofile" - default POSIX_AEP_CHOICE_NONE + default POSIX_AEP_CHOICE_ZEPHYR help This choice is intended to help users select the correct POSIX profile for their application. Choices are based on IEEE 1003.13-2003 (now inactive / reserved) and From 0756a6224d8e3881e9691b59520599b7866885db Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Sat, 12 Apr 2025 08:55:16 -0400 Subject: [PATCH 6/6] posix: options: add keep-sorted-start and -stop Add zephyr-keep-sorted-start and zephyr-keep-sorted-stop comments. Signed-off-by: Chris Friedt --- lib/posix/CMakeLists.txt | 2 ++ lib/posix/options/Kconfig | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/lib/posix/CMakeLists.txt b/lib/posix/CMakeLists.txt index 49d260f0a9bd3..9a40cad191b26 100644 --- a/lib/posix/CMakeLists.txt +++ b/lib/posix/CMakeLists.txt @@ -1,7 +1,9 @@ # SPDX-License-Identifier: Apache-2.0 +# zephyr-keep-sorted-start add_subdirectory_ifdef(CONFIG_EVENTFD eventfd) add_subdirectory_ifdef(CONFIG_POSIX_C_LANG_SUPPORT_R c_lang_support_r) add_subdirectory_ifdef(CONFIG_POSIX_C_LIB_EXT c_lib_ext) add_subdirectory_ifdef(CONFIG_POSIX_SHELL shell) add_subdirectory_ifdef(CONFIG_POSIX_SYSTEM_INTERFACES options) +# zephyr-keep-sorted-stop diff --git a/lib/posix/options/Kconfig b/lib/posix/options/Kconfig index d635e07b23dba..3f072a293f6be 100644 --- a/lib/posix/options/Kconfig +++ b/lib/posix/options/Kconfig @@ -4,6 +4,7 @@ # # SPDX-License-Identifier: Apache-2.0 +# zephyr-keep-sorted-start rsource "Kconfig.aio" rsource "Kconfig.barrier" rsource "Kconfig.device_io" @@ -23,13 +24,16 @@ rsource "Kconfig.signal" rsource "Kconfig.spinlock" rsource "Kconfig.sync_io" rsource "Kconfig.timer" +# zephyr-keep-sorted-stop menu "X/Open system interfaces" +# zephyr-keep-sorted-start rsource "Kconfig.xsi_realtime" rsource "Kconfig.xsi_single_process" rsource "Kconfig.xsi_streams" rsource "Kconfig.xsi_system_logging" rsource "Kconfig.xsi_threads_ext" +# zephyr-keep-sorted-stop endmenu # "X/Open system interfaces"