From b2e38a102886544e1619bea7e4afa46a6a0b2f8c Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 4 Nov 2025 11:58:59 +0200 Subject: [PATCH 1/2] sys: getopt: Rename getopt to sys_getopt to avoid conflicts with Posix Summary: As Zephyr getopt is not really compatible with Posix getopt, rename Zephyr getopt to sys_getopt. Background: Zephyr getopt module was introduced in #31356 to be used by the shell. Zephyr's getopt is not the standard one. It has multiple APIs which make it more suited for a system like Zephyr where different components may want to use it for different purposes. Including APIs to init it, get and set its internal state etc. Several Zephyr modules (shell, net, wifi, ztest) use this getopt with these special APIs. The getopt module is bundled in the POSIX compatibility API subsystem (CONFIG_POSIX_C_LIB_EXT). Problem description: As it is not the standard getopt(), no C library can possibly provide a Zephyr compatible version (even if such C library were to provide a standard getopt()). As it is bundled in Zephyr's POSIX API in CONFIG_POSIX_C_LIB_EXT), multiple components that depend on it are selecting CONFIG_POSIX_C_LIB_EXT. Zephyr core components should not depend on the POSIX API in this way. Changes done in this commit: Rename the getopt*() APIs to sys_getopt*() and move them into a module under lib/utils with its own Kconfig option to enable it. Zephyr's users are changed to use this new component. The POSIX subsystem can continue providing getopt() by calling the new sys_getopt() and in that way retain backwards compatibility for external users. Signed-off-by: Jukka Rissanen (cherry picked from commit 22f9ef0a3386e02bdcd9779d0eb68a3008af5bc6) --- doc/services/shell/index.rst | 20 +- include/zephyr/shell/shell.h | 4 +- .../zephyr/sys/sys_getopt.h | 73 ++-- lib/posix/c_lib_ext/CMakeLists.txt | 4 - lib/posix/c_lib_ext/Kconfig | 17 +- lib/posix/shell/uname.c | 4 +- lib/utils/CMakeLists.txt | 3 + lib/utils/Kconfig | 17 + lib/{posix/c_lib_ext => utils}/getopt/README | 2 + .../c_lib_ext => utils}/getopt/getopt.c | 31 +- .../getopt/getopt_common.c | 28 +- .../getopt/getopt_common.h | 2 +- .../c_lib_ext => utils}/getopt/getopt_long.c | 53 +-- samples/shields/npm13xx_ek/src/main.c | 1 - samples/shields/npm6001_ek/src/main.c | 18 +- samples/subsys/shell/shell_module/src/main.c | 8 +- subsys/crc/crc_shell.c | 2 +- subsys/net/l2/wifi/wifi_shell.c | 365 +++++++++--------- .../wifi_credentials/wifi_credentials_shell.c | 27 +- subsys/shell/Kconfig | 4 +- subsys/shell/modules/Kconfig | 2 +- subsys/shell/modules/devmem_service.c | 31 +- subsys/shell/modules/kernel_service/uptime.c | 2 +- subsys/shell/shell.c | 2 +- subsys/testsuite/ztest/src/ztest.c | 22 +- 25 files changed, 378 insertions(+), 364 deletions(-) rename lib/posix/c_lib_ext/getopt/getopt.h => include/zephyr/sys/sys_getopt.h (56%) rename lib/{posix/c_lib_ext => utils}/getopt/README (98%) rename lib/{posix/c_lib_ext => utils}/getopt/getopt.c (91%) rename lib/{posix/c_lib_ext => utils}/getopt/getopt_common.c (64%) rename lib/{posix/c_lib_ext => utils}/getopt/getopt_common.h (83%) rename lib/{posix/c_lib_ext => utils}/getopt/getopt_long.c (90%) diff --git a/doc/services/shell/index.rst b/doc/services/shell/index.rst index 77b891175f7c2..7032d77b582b5 100644 --- a/doc/services/shell/index.rst +++ b/doc/services/shell/index.rst @@ -678,16 +678,16 @@ The shell module supports the following meta keys: This feature is activated by :kconfig:option:`CONFIG_SHELL_METAKEYS` set to ``y``. -Getopt Feature -***************** +sys_getopt Feature +****************** Some shell users apart from subcommands might need to use options as well. the arguments string, looking for supported options. Typically, this task is accomplished by the ``getopt`` family functions. -For this purpose shell supports the getopt and getopt_long libraries available -in the FreeBSD project. This feature is activated by: -:kconfig:option:`CONFIG_POSIX_C_LIB_EXT` set to ``y`` and :kconfig:option:`CONFIG_GETOPT_LONG` +For this purpose shell supports a variant of the getopt and getopt_long libraries from +the FreeBSD project called sys_getopt and sys_getopt_long. This feature is activated by: +:kconfig:option:`CONFIG_GETOPT` set to ``y`` and :kconfig:option:`CONFIG_GETOPT_LONG` set to ``y``. This feature can be used in thread safe as well as non thread safe manner. @@ -699,7 +699,7 @@ An example non-thread safe usage: .. code-block:: c char *cvalue = NULL; - while ((char c = getopt(argc, argv, "abhc:")) != -1) { + while ((char c = sys_getopt(argc, argv, "abhc:")) != -1) { switch (c) { case 'c': cvalue = optarg; @@ -714,9 +714,9 @@ An example thread safe usage: .. code-block:: c char *cvalue = NULL; - struct getopt_state *state; - while ((char c = getopt(argc, argv, "abhc:")) != -1) { - state = getopt_state_get(); + struct sys_getopt_state *state; + while ((char c = sys_getopt(argc, argv, "abhc:")) != -1) { + state = sys_getopt_state_get(); switch (c) { case 'c': cvalue = state->optarg; @@ -726,7 +726,7 @@ An example thread safe usage: } } -Thread safe getopt functionality is activated by +Thread safe sys_getopt functionality is activated by :kconfig:option:`CONFIG_SHELL_GETOPT` set to ``y``. Obscured Input Feature diff --git a/include/zephyr/shell/shell.h b/include/zephyr/shell/shell.h index ba275c5393c10..c6f9317c43784 100644 --- a/include/zephyr/shell/shell.h +++ b/include/zephyr/shell/shell.h @@ -20,7 +20,7 @@ #include #if defined CONFIG_SHELL_GETOPT -#include +#include #endif #ifdef __cplusplus @@ -995,7 +995,7 @@ struct shell_ctx { #if defined CONFIG_SHELL_GETOPT /*!< getopt context for a shell backend. */ - struct getopt_state getopt; + struct sys_getopt_state getopt; #endif uint16_t cmd_buff_len; /*!< Command length.*/ diff --git a/lib/posix/c_lib_ext/getopt/getopt.h b/include/zephyr/sys/sys_getopt.h similarity index 56% rename from lib/posix/c_lib_ext/getopt/getopt.h rename to include/zephyr/sys/sys_getopt.h index eb0641f6c9045..7ffaf248f23cb 100644 --- a/lib/posix/c_lib_ext/getopt/getopt.h +++ b/include/zephyr/sys/sys_getopt.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef _GETOPT_H__ -#define _GETOPT_H__ +#ifndef ZEPHYR_INCLUDE_SYS_GETOPT_H_ +#define ZEPHYR_INCLUDE_SYS_GETOPT_H_ #ifdef __cplusplus extern "C" { @@ -13,7 +13,7 @@ extern "C" { #include -struct getopt_state { +struct sys_getopt_state { int opterr; /* if error message should be printed */ int optind; /* index into parent argv vector */ int optopt; /* character checked for validity */ @@ -28,17 +28,17 @@ struct getopt_state { #endif }; -extern int optreset; /* reset getopt */ -extern char *optarg; -extern int opterr; -extern int optind; -extern int optopt; +extern int sys_getopt_optreset; /* reset getopt */ +extern char *sys_getopt_optarg; +extern int sys_getopt_opterr; +extern int sys_getopt_optind; +extern int sys_getopt_optopt; -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 +#define sys_getopt_no_argument 0 +#define sys_getopt_required_argument 1 +#define sys_getopt_optional_argument 2 -struct option { +struct sys_getopt_option { /* name of long option */ const char *name; /* @@ -53,39 +53,54 @@ struct option { }; /* Function initializes getopt_state structure for current thread */ -void getopt_init(void); +void sys_getopt_init(void); /* Function returns getopt_state structure for the current thread. */ -struct getopt_state *getopt_state_get(void); +struct sys_getopt_state *sys_getopt_state_get(void); /** * @brief Parses the command-line arguments. * - * The getopt_long() function works like @ref getopt() except + * @note This function is based on FreeBSD implementation but it does not + * support environment variable: POSIXLY_CORRECT. + * + * @param[in] nargc Arguments count. + * @param[in] nargv Arguments. + * @param[in] ostr String containing the legitimate option characters. + * + * @return If an option was successfully found, function returns + * the option character. + */ +int sys_getopt(int nargc, char *const nargv[], const char *ostr); + +/** + * @brief Parses the command-line arguments. + * + * The sys_getopt_long() function works like @ref sys_getopt() except * it also accepts long options, started with two dashes. * * @note This function is based on FreeBSD implementation but it does not * support environment variable: POSIXLY_CORRECT. * - * @param[in] argc Arguments count. - * @param[in] argv Arguments. + * @param[in] nargc Arguments count. + * @param[in] nargv Arguments. * @param[in] options String containing the legitimate option characters. * @param[in] long_options Pointer to the first element of an array of - * @a struct z_option. - * @param[in] long_idx If long_idx is not NULL, it points to a variable + * @a struct sys_getopt_option. + * @param[in] idx If idx is not NULL, it points to a variable * which is set to the index of the long option relative * to @p long_options. * * @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 sys_getopt_long(int nargc, char *const *nargv, const char *options, + const struct sys_getopt_option *long_options, int *idx); /** * @brief Parses the command-line arguments. * - * The getopt_long_only() function works like @ref getopt_long(), + * The sys_getopt_long_only() function works like @ref sys_getopt_long(), * but '-' as well as "--" can indicate a long option. If an option that starts * with '-' (not "--") doesn't match a long option, but does match a short * option, it is parsed as a short option instead. @@ -93,23 +108,23 @@ int getopt_long(int nargc, char *const *nargv, const char *options, * @note This function is based on FreeBSD implementation but it does not * support environment variable: POSIXLY_CORRECT. * - * @param[in] argc Arguments count. - * @param[in] argv Arguments. + * @param[in] nargc Arguments count. + * @param[in] nargv Arguments. * @param[in] options String containing the legitimate option characters. * @param[in] long_options Pointer to the first element of an array of - * @a struct option. - * @param[in] long_idx If long_idx is not NULL, it points to a variable + * @a struct sys_getopt_option. + * @param[in] idx If idx is not NULL, it points to a variable * which is set to the index of the long option relative * to @p long_options. * * @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 sys_getopt_long_only(int nargc, char *const *nargv, const char *options, + const struct sys_getopt_option *long_options, int *idx); #ifdef __cplusplus } #endif -#endif /* _GETOPT_H__ */ +#endif /* ZEPHYR_INCLUDE_SYS_GETOPT_H_ */ diff --git a/lib/posix/c_lib_ext/CMakeLists.txt b/lib/posix/c_lib_ext/CMakeLists.txt index ee0581cb22246..46923199e61f4 100644 --- a/lib/posix/c_lib_ext/CMakeLists.txt +++ b/lib/posix/c_lib_ext/CMakeLists.txt @@ -10,8 +10,4 @@ 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/c_lib_ext/Kconfig b/lib/posix/c_lib_ext/Kconfig index 9dc4ae52520e0..8c9751d0914bd 100644 --- a/lib/posix/c_lib_ext/Kconfig +++ b/lib/posix/c_lib_ext/Kconfig @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -menuconfig POSIX_C_LIB_EXT +config POSIX_C_LIB_EXT bool "POSIX general C library extension" help Select 'y' here and Zephyr will provide an implementation of the POSIX_C_LIB_EXT Option @@ -12,18 +12,3 @@ menuconfig POSIX_C_LIB_EXT For more information, please see https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_subprofiles.html - -if POSIX_C_LIB_EXT - -config GETOPT_LONG - bool "Getopt long library support" - help - This option adds support of the getopt long. - Different shell backends are using their own instance of getopt to - not interfere with each other. - All not shell threads share one global instance of getopt state, hence - apart from shell this library is not thread safe. User can add support - for other threads by extending function getopt_state_get in - getopt_common.c file. - -endif # POSIX_C_LIB_EXT diff --git a/lib/posix/shell/uname.c b/lib/posix/shell/uname.c index 54e12de9a5930..176a28504a54b 100644 --- a/lib/posix/shell/uname.c +++ b/lib/posix/shell/uname.c @@ -42,7 +42,7 @@ static void uname_print_usage(const struct shell *sh) static int uname_cmd_handler(const struct shell *sh, size_t argc, char **argv) { - struct getopt_state *state = getopt_state_get(); + struct sys_getopt_state *state = sys_getopt_state_get(); struct utsname info; unsigned int set; int option; @@ -54,7 +54,7 @@ static int uname_cmd_handler(const struct shell *sh, size_t argc, char **argv) /* Get the uname options */ optind = 1; - while ((option = getopt(argc, argv, "asonrvmpi")) != -1) { + while ((option = sys_getopt(argc, argv, "asonrvmpi")) != -1) { switch (option) { case 'a': set = UNAME_ALL; diff --git a/lib/utils/CMakeLists.txt b/lib/utils/CMakeLists.txt index f6ab864d4640e..2d03b1f04aa44 100644 --- a/lib/utils/CMakeLists.txt +++ b/lib/utils/CMakeLists.txt @@ -11,6 +11,9 @@ zephyr_sources( bitmask.c ) +zephyr_library_sources_ifdef(CONFIG_GETOPT getopt/getopt.c getopt/getopt_common.c) +zephyr_library_sources_ifdef(CONFIG_GETOPT_LONG getopt/getopt_long.c) + zephyr_sources_ifdef(CONFIG_ONOFF onoff.c) zephyr_sources_ifdef(CONFIG_NOTIFY notify.c) diff --git a/lib/utils/Kconfig b/lib/utils/Kconfig index 4db79272bbafe..c22eae50fbf01 100644 --- a/lib/utils/Kconfig +++ b/lib/utils/Kconfig @@ -81,4 +81,21 @@ config COBS help Enable consistent overhead byte stuffing +config GETOPT + bool "Getopt library support" + help + This option adds support of the sys_getopt API. + +config GETOPT_LONG + bool "Getopt long library support" + depends on GETOPT + help + This option adds support of the getopt long. + Different shell backends are using their own instance of getopt to + not interfere with each other. + All not shell threads share one global instance of getopt state, hence + apart from shell this library is not thread safe. User can add support + for other threads by extending function sys_getopt_state_get in + getopt_common.c file. + endmenu diff --git a/lib/posix/c_lib_ext/getopt/README b/lib/utils/getopt/README similarity index 98% rename from lib/posix/c_lib_ext/getopt/README rename to lib/utils/getopt/README index 606e93b4e6b58..f67390d26377d 100644 --- a/lib/posix/c_lib_ext/getopt/README +++ b/lib/utils/getopt/README @@ -1,3 +1,5 @@ +SPDX-License-Identifier: BSD-3-Clause + [GetOpt] ##################### diff --git a/lib/posix/c_lib_ext/getopt/getopt.c b/lib/utils/getopt/getopt.c similarity index 91% rename from lib/posix/c_lib_ext/getopt/getopt.c rename to lib/utils/getopt/getopt.c index a81e0ca279a2d..ceb600e10f4aa 100644 --- a/lib/posix/c_lib_ext/getopt/getopt.c +++ b/lib/utils/getopt/getopt.c @@ -30,26 +30,21 @@ */ #include -#ifdef CONFIG_NATIVE_LIBC -#include -#else -#include -#endif -#include "getopt.h" +#include #include "getopt_common.h" #include -LOG_MODULE_REGISTER(getopt); +LOG_MODULE_REGISTER(sys_getopt); #define BADCH ((int)'?') #define BADARG ((int)':') #define EMSG "" -void getopt_init(void) +void sys_getopt_init(void) { - struct getopt_state *state; + struct sys_getopt_state *state; - state = getopt_state_get(); + state = sys_getopt_state_get(); state->opterr = 1; state->optind = 1; @@ -64,24 +59,24 @@ void getopt_init(void) state->nonopt_end = -1; /* first option after non options (for permute) */ #endif - opterr = 1; - optind = 1; - optopt = 0; - optreset = 0; - optarg = NULL; + sys_getopt_opterr = 1; + sys_getopt_optind = 1; + sys_getopt_optopt = 0; + sys_getopt_optreset = 0; + sys_getopt_optarg = NULL; } /* * getopt -- * Parse argc/argv argument vector. */ -int getopt(int nargc, char *const nargv[], const char *ostr) +int sys_getopt(int nargc, char *const nargv[], const char *ostr) { - struct getopt_state *state; + struct sys_getopt_state *state; char *oli; /* option letter list index */ /* get getopt state of the current thread */ - state = getopt_state_get(); + state = sys_getopt_state_get(); if (state->optreset || *state->place == 0) { /* update scanning pointer */ state->optreset = 0; diff --git a/lib/posix/c_lib_ext/getopt/getopt_common.c b/lib/utils/getopt/getopt_common.c similarity index 64% rename from lib/posix/c_lib_ext/getopt/getopt_common.c rename to lib/utils/getopt/getopt_common.c index 2599d2c2d98bd..bfc3d8d8fc2d4 100644 --- a/lib/posix/c_lib_ext/getopt/getopt_common.c +++ b/lib/utils/getopt/getopt_common.c @@ -9,21 +9,21 @@ #include #endif -#include "getopt.h" +#include /* Referring below variables is not thread safe. They reflects getopt state * only when 1 thread is using getopt. * 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 sys_getopt_opterr = 1; /* if error message should be printed */ +int sys_getopt_optind = 1; /* index into parent argv vector */ +int sys_getopt_optopt; /* character checked for validity */ +int sys_getopt_optreset; /* reset getopt */ +char *sys_getopt_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 = { +static struct sys_getopt_state m_getopt_common_state = { .opterr = 1, .optind = 1, .optopt = 0, @@ -41,17 +41,17 @@ static struct getopt_state m_getopt_common_state = { /* This function is not thread safe. All threads using getopt are calling * this function. */ -void z_getopt_global_state_update(struct getopt_state *state) +void z_getopt_global_state_update(struct sys_getopt_state *state) { - opterr = state->opterr; - optind = state->optind; - optopt = state->optopt; - optreset = state->optreset; - optarg = state->optarg; + sys_getopt_opterr = state->opterr; + sys_getopt_optind = state->optind; + sys_getopt_optopt = state->optopt; + sys_getopt_optreset = state->optreset; + sys_getopt_optarg = state->optarg; } /* It is internal getopt API function, it shall not be called by the user. */ -struct getopt_state *getopt_state_get(void) +struct sys_getopt_state *sys_getopt_state_get(void) { #if CONFIG_SHELL_GETOPT k_tid_t tid; diff --git a/lib/posix/c_lib_ext/getopt/getopt_common.h b/lib/utils/getopt/getopt_common.h similarity index 83% rename from lib/posix/c_lib_ext/getopt/getopt_common.h rename to lib/utils/getopt/getopt_common.h index b0ec82bf9212e..59d916cfd6037 100644 --- a/lib/posix/c_lib_ext/getopt/getopt_common.h +++ b/lib/utils/getopt/getopt_common.h @@ -14,7 +14,7 @@ extern "C" { /* This function is not thread safe. All threads using getopt are calling * this function. */ -void z_getopt_global_state_update(struct getopt_state *state); +void z_getopt_global_state_update(struct sys_getopt_state *state); #ifdef __cplusplus } diff --git a/lib/posix/c_lib_ext/getopt/getopt_long.c b/lib/utils/getopt/getopt_long.c similarity index 90% rename from lib/posix/c_lib_ext/getopt/getopt_long.c rename to lib/utils/getopt/getopt_long.c index e39a13b3bbcf5..8e51a6a8ba010 100644 --- a/lib/posix/c_lib_ext/getopt/getopt_long.c +++ b/lib/utils/getopt/getopt_long.c @@ -1,5 +1,6 @@ /* $OpenBSD: getopt_long.c,v 1.22 2006/10/04 21:29:04 jmc Exp $ */ /* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ +/* SPDX-License-Identifier: BSD-3-Clause */ /* * Copyright (c) 2002 Todd C. Miller @@ -50,11 +51,11 @@ */ #include -#include "getopt.h" +#include #include "getopt_common.h" #include -LOG_MODULE_DECLARE(getopt); +LOG_MODULE_DECLARE(sys_getopt); #define GNU_COMPATIBLE /* Be more compatible, configure's use us! */ @@ -78,10 +79,10 @@ LOG_MODULE_DECLARE(getopt); #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 sys_getopt_state *, int, char *const *, const char *, + const struct sys_getopt_option *, int *, int); +static int parse_long_options(struct sys_getopt_state *, char *const *, const char *, + const struct sys_getopt_option *, int *, int, int); static int gcd(int, int); static void permute_args(int, int, int, char *const *); @@ -161,8 +162,9 @@ static void permute_args(int panonopt_start, int panonopt_end, int opt_end, char * 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 sys_getopt_state *state, char *const *nargv, + const char *options, const struct sys_getopt_option *long_options, + int *idx, int short_too, int flags) { char *current_argv, *has_equal; #ifdef GNU_COMPATIBLE @@ -246,7 +248,7 @@ static int parse_long_options(struct getopt_state *state, char *const *nargv, co return BADCH; } if (match != -1) { /* option found */ - if (long_options[match].has_arg == no_argument && has_equal) { + if (long_options[match].has_arg == sys_getopt_no_argument && has_equal) { if (PRINT_ERROR) { LOG_WRN(NOARG, #ifdef GNU_COMPATIBLE @@ -268,18 +270,19 @@ static int parse_long_options(struct getopt_state *state, char *const *nargv, co return BADARG; #endif } - if (long_options[match].has_arg == required_argument || - long_options[match].has_arg == optional_argument) { + if (long_options[match].has_arg == sys_getopt_required_argument || + long_options[match].has_arg == sys_getopt_optional_argument) { if (has_equal) { state->optarg = has_equal; - } else if (long_options[match].has_arg == required_argument) { + } else if (long_options[match].has_arg == sys_getopt_required_argument) { /* * optional argument doesn't use next nargv */ state->optarg = nargv[state->optind++]; } } - if ((long_options[match].has_arg == required_argument) && (state->optarg == NULL)) { + if ((long_options[match].has_arg == sys_getopt_required_argument) && + (state->optarg == NULL)) { /* * Missing argument; leading ':' indicates no error * should be generated. @@ -332,9 +335,9 @@ static int parse_long_options(struct getopt_state *state, char *const *nargv, co * 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 sys_getopt_state *state, int nargc, char *const *nargv, + const char *options, const struct sys_getopt_option *long_options, + int *idx, int flags) { char *oli; /* option letter list index */ int optchar, short_too; @@ -461,7 +464,7 @@ static int getopt_internal(struct getopt_state *state, int nargc, char *const *n * Check long options if: * 1) we were passed some * 2) the arg is not just "-" - * 3) either the arg starts with -- we are getopt_long_only() + * 3) either the arg starts with -- we are sys_getopt_long_only() */ if (long_options != NULL && state->place != nargv[state->optind] && (*(state->place) == '-' || (flags & FLAG_LONGONLY))) { @@ -563,14 +566,14 @@ static int getopt_internal(struct getopt_state *state, int nargc, char *const *n * 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 sys_getopt_long(int nargc, char *const *nargv, const char *options, + const struct sys_getopt_option *long_options, int *idx) { - struct getopt_state *state; + struct sys_getopt_state *state; int ret; /* Get state of the current thread */ - state = getopt_state_get(); + state = sys_getopt_state_get(); ret = getopt_internal(state, nargc, nargv, options, long_options, idx, FLAG_PERMUTE); @@ -583,14 +586,14 @@ int getopt_long(int nargc, char *const *nargv, const char *options, * 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 sys_getopt_long_only(int nargc, char *const *nargv, const char *options, + const struct sys_getopt_option *long_options, int *idx) { - struct getopt_state *state; + struct sys_getopt_state *state; int ret; /* Get state of the current thread */ - state = getopt_state_get(); + state = sys_getopt_state_get(); ret = getopt_internal(state, nargc, nargv, options, long_options, idx, FLAG_PERMUTE | FLAG_LONGONLY); diff --git a/samples/shields/npm13xx_ek/src/main.c b/samples/shields/npm13xx_ek/src/main.c index 0473c56623532..11324ecd4856a 100644 --- a/samples/shields/npm13xx_ek/src/main.c +++ b/samples/shields/npm13xx_ek/src/main.c @@ -14,7 +14,6 @@ #include #include #include -#include #define SLEEP_TIME_MS 100 #define UPDATE_TIME_MS 2000 diff --git a/samples/shields/npm6001_ek/src/main.c b/samples/shields/npm6001_ek/src/main.c index ec3e24e3354fd..f4cfbcac6e9da 100644 --- a/samples/shields/npm6001_ek/src/main.c +++ b/samples/shields/npm6001_ek/src/main.c @@ -15,7 +15,7 @@ #include #include -#include +#include struct regulators_map { const char *name; @@ -303,12 +303,12 @@ static int cmd_gpio_configure(const struct shell *sh, size_t argc, char **argv) gpio_pin_t pin = 0U; gpio_flags_t flags = 0U; - static const struct option long_options[] = { - {"pin", required_argument, NULL, 'p'}, - {"direction", required_argument, NULL, 'd'}, - {"high-drive", no_argument, &high_drive, 1}, - {"pull-down", no_argument, &pull_down, 1}, - {"cmos", no_argument, &cmos, 1}, + static const struct sys_getopt_option long_options[] = { + {"pin", sys_getopt_required_argument, NULL, 'p'}, + {"direction", sys_getopt_required_argument, NULL, 'd'}, + {"high-drive", sys_getopt_no_argument, &high_drive, 1}, + {"pull-down", sys_getopt_no_argument, &pull_down, 1}, + {"cmos", sys_getopt_no_argument, &cmos, 1}, {NULL, 0, NULL, 0}, }; @@ -316,8 +316,8 @@ static int cmd_gpio_configure(const struct shell *sh, size_t argc, char **argv) pull_down = 0; cmos = 0; - while ((opt = getopt_long(argc, argv, "p:d:", long_options, - &long_index)) != -1) { + while ((opt = sys_getopt_long(argc, argv, "p:d:", long_options, + &long_index)) != -1) { switch (opt) { case 0: /* options setting a flag, do nothing */ diff --git a/samples/subsys/shell/shell_module/src/main.c b/samples/subsys/shell/shell_module/src/main.c index 7c633eb7c7f7d..7122249963360 100644 --- a/samples/subsys/shell/shell_module/src/main.c +++ b/samples/subsys/shell/shell_module/src/main.c @@ -109,14 +109,14 @@ static int cmd_demo_board(const struct shell *sh, size_t argc, char **argv) static int cmd_demo_getopt_ts(const struct shell *sh, size_t argc, char **argv) { - struct getopt_state *state; + struct sys_getopt_state *state; char *cvalue = NULL; int aflag = 0; int bflag = 0; int c; - while ((c = getopt(argc, argv, "abhc:")) != -1) { - state = getopt_state_get(); + while ((c = sys_getopt(argc, argv, "abhc:")) != -1) { + state = sys_getopt_state_get(); switch (c) { case 'a': aflag = 1; @@ -166,7 +166,7 @@ static int cmd_demo_getopt(const struct shell *sh, size_t argc, int bflag = 0; int c; - while ((c = getopt(argc, argv, "abhc:")) != -1) { + while ((c = sys_getopt(argc, argv, "abhc:")) != -1) { switch (c) { case 'a': aflag = 1; diff --git a/subsys/crc/crc_shell.c b/subsys/crc/crc_shell.c index 189ec764806e6..a1f26300616d9 100644 --- a/subsys/crc/crc_shell.c +++ b/subsys/crc/crc_shell.c @@ -81,7 +81,7 @@ static int cmd_crc(const struct shell *sh, size_t argc, char **argv) optind = 1; - while ((rv = getopt(argc, argv, "fhlp:rs:t:")) != -1) { + while ((rv = sys_getopt(argc, argv, "fhlp:rs:t:")) != -1) { switch (rv) { case 'f': first = true; diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 46f64dcb4f03b..c94ee5c159d45 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -97,7 +97,7 @@ static struct net_if *get_iface(enum iface_type type, int argc, char *argv[]) int iface_index = -1; /* Parse arguments manually to find -i or --iface, - * it's intentional not to use getopt() here to avoid + * it's intentional not to use sys_getopt() here to avoid * permuting the arguments. */ for (int i = 1; i < argc; i++) { @@ -583,44 +583,44 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"ssid", required_argument, 0, 's'}, - {"passphrase", required_argument, 0, 'p'}, - {"key-mgmt", required_argument, 0, 'k'}, - {"ieee-80211w", required_argument, 0, 'w'}, - {"bssid", required_argument, 0, 'm'}, - {"band", required_argument, 0, 'b'}, - {"channel", required_argument, 0, 'c'}, - {"timeout", required_argument, 0, 't'}, - {"anon-id", required_argument, 0, 'a'}, - {"bandwidth", required_argument, 0, 'B'}, - {"key1-pwd", required_argument, 0, 'K'}, - {"key2-pwd", required_argument, 0, 'K'}, - {"wpa3-enterprise", required_argument, 0, 'S'}, - {"TLS-cipher", required_argument, 0, 'T'}, - {"verify-peer-cert", required_argument, 0, 'A'}, - {"eap-version", required_argument, 0, 'V'}, - {"eap-id1", required_argument, 0, 'I'}, - {"eap-id2", required_argument, 0, 'I'}, - {"eap-id3", required_argument, 0, 'I'}, - {"eap-id4", required_argument, 0, 'I'}, - {"eap-id5", required_argument, 0, 'I'}, - {"eap-id6", required_argument, 0, 'I'}, - {"eap-id7", required_argument, 0, 'I'}, - {"eap-id8", required_argument, 0, 'I'}, - {"eap-pwd1", required_argument, 0, 'P'}, - {"eap-pwd2", required_argument, 0, 'P'}, - {"eap-pwd3", required_argument, 0, 'P'}, - {"eap-pwd4", required_argument, 0, 'P'}, - {"eap-pwd5", required_argument, 0, 'P'}, - {"eap-pwd6", required_argument, 0, 'P'}, - {"eap-pwd7", required_argument, 0, 'P'}, - {"eap-pwd8", required_argument, 0, 'P'}, - {"ignore-broadcast-ssid", required_argument, 0, 'g'}, - {"ieee-80211r", no_argument, 0, 'R'}, - {"iface", required_argument, 0, 'i'}, - {"help", no_argument, 0, 'h'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"ssid", sys_getopt_required_argument, 0, 's'}, + {"passphrase", sys_getopt_required_argument, 0, 'p'}, + {"key-mgmt", sys_getopt_required_argument, 0, 'k'}, + {"ieee-80211w", sys_getopt_required_argument, 0, 'w'}, + {"bssid", sys_getopt_required_argument, 0, 'm'}, + {"band", sys_getopt_required_argument, 0, 'b'}, + {"channel", sys_getopt_required_argument, 0, 'c'}, + {"timeout", sys_getopt_required_argument, 0, 't'}, + {"anon-id", sys_getopt_required_argument, 0, 'a'}, + {"bandwidth", sys_getopt_required_argument, 0, 'B'}, + {"key1-pwd", sys_getopt_required_argument, 0, 'K'}, + {"key2-pwd", sys_getopt_required_argument, 0, 'K'}, + {"wpa3-enterprise", sys_getopt_required_argument, 0, 'S'}, + {"TLS-cipher", sys_getopt_required_argument, 0, 'T'}, + {"verify-peer-cert", sys_getopt_required_argument, 0, 'A'}, + {"eap-version", sys_getopt_required_argument, 0, 'V'}, + {"eap-id1", sys_getopt_required_argument, 0, 'I'}, + {"eap-id2", sys_getopt_required_argument, 0, 'I'}, + {"eap-id3", sys_getopt_required_argument, 0, 'I'}, + {"eap-id4", sys_getopt_required_argument, 0, 'I'}, + {"eap-id5", sys_getopt_required_argument, 0, 'I'}, + {"eap-id6", sys_getopt_required_argument, 0, 'I'}, + {"eap-id7", sys_getopt_required_argument, 0, 'I'}, + {"eap-id8", sys_getopt_required_argument, 0, 'I'}, + {"eap-pwd1", sys_getopt_required_argument, 0, 'P'}, + {"eap-pwd2", sys_getopt_required_argument, 0, 'P'}, + {"eap-pwd3", sys_getopt_required_argument, 0, 'P'}, + {"eap-pwd4", sys_getopt_required_argument, 0, 'P'}, + {"eap-pwd5", sys_getopt_required_argument, 0, 'P'}, + {"eap-pwd6", sys_getopt_required_argument, 0, 'P'}, + {"eap-pwd7", sys_getopt_required_argument, 0, 'P'}, + {"eap-pwd8", sys_getopt_required_argument, 0, 'P'}, + {"ignore-broadcast-ssid", sys_getopt_required_argument, 0, 'g'}, + {"ieee-80211r", sys_getopt_no_argument, 0, 'R'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, + {"help", sys_getopt_no_argument, 0, 'h'}, {0, 0, 0, 0}}; char *endptr; int idx = 1; @@ -648,9 +648,9 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv params->bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ; params->verify_peer_cert = false; - while ((opt = getopt_long(argc, argv, "s:p:k:e:w:b:c:m:t:a:B:K:S:T:A:V:I:P:g:Rh:i:", + while ((opt = sys_getopt_long(argc, argv, "s:p:k:e:w:b:c:m:t:a:B:K:S:T:A:V:I:P:g:Rh:i:", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 's': params->ssid = state->optarg; @@ -1017,26 +1017,26 @@ static int wifi_scan_args_to_params(const struct shell *sh, { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"type", required_argument, 0, 't'}, - {"bands", required_argument, 0, 'b'}, - {"dwell_time_active", required_argument, 0, 'a'}, - {"dwell_time_passive", required_argument, 0, 'p'}, - {"ssid", required_argument, 0, 's'}, - {"max_bss", required_argument, 0, 'm'}, - {"chans", required_argument, 0, 'c'}, - {"iface", required_argument, 0, 'i'}, - {"help", no_argument, 0, 'h'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"type", sys_getopt_required_argument, 0, 't'}, + {"bands", sys_getopt_required_argument, 0, 'b'}, + {"dwell_time_active", sys_getopt_required_argument, 0, 'a'}, + {"dwell_time_passive", sys_getopt_required_argument, 0, 'p'}, + {"ssid", sys_getopt_required_argument, 0, 's'}, + {"max_bss", sys_getopt_required_argument, 0, 'm'}, + {"chans", sys_getopt_required_argument, 0, 'c'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, + {"help", sys_getopt_no_argument, 0, 'h'}, {0, 0, 0, 0}}; int val; int opt_num = 0; *do_scan = true; - while ((opt = getopt_long(argc, argv, "t:b:a:p:s:m:c:i:h", + while ((opt = sys_getopt_long(argc, argv, "t:b:a:p:s:m:c:i:h", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 't': if (!strncasecmp(state->optarg, "passive", 7)) { @@ -1729,36 +1729,36 @@ static int twt_args_to_params(const struct shell *sh, size_t argc, char *argv[], { int opt; int opt_index = 0; - struct getopt_state *state; + struct sys_getopt_state *state; long value; double twt_mantissa_scale = 0.0; double twt_interval_scale = 0.0; uint16_t scale = 1000; int exponent = 0; - static const struct option long_options[] = { - {"negotiation-type", required_argument, 0, 'n'}, - {"setup-cmd", required_argument, 0, 'c'}, - {"dialog-token", required_argument, 0, 't'}, - {"flow-id", required_argument, 0, 'f'}, - {"responder", required_argument, 0, 'r'}, - {"trigger", required_argument, 0, 'T'}, - {"implicit", required_argument, 0, 'I'}, - {"announce", required_argument, 0, 'a'}, - {"wake-interval", required_argument, 0, 'w'}, - {"interval", required_argument, 0, 'p'}, - {"wake-ahead-duration", required_argument, 0, 'D'}, - {"info-disable", required_argument, 0, 'd'}, - {"exponent", required_argument, 0, 'e'}, - {"mantissa", required_argument, 0, 'm'}, - {"iface", required_argument, 0, 'i'}, - {"help", no_argument, 0, 'h'}, + static const struct sys_getopt_option long_options[] = { + {"negotiation-type", sys_getopt_required_argument, 0, 'n'}, + {"setup-cmd", sys_getopt_required_argument, 0, 'c'}, + {"dialog-token", sys_getopt_required_argument, 0, 't'}, + {"flow-id", sys_getopt_required_argument, 0, 'f'}, + {"responder", sys_getopt_required_argument, 0, 'r'}, + {"trigger", sys_getopt_required_argument, 0, 'T'}, + {"implicit", sys_getopt_required_argument, 0, 'I'}, + {"announce", sys_getopt_required_argument, 0, 'a'}, + {"wake-interval", sys_getopt_required_argument, 0, 'w'}, + {"interval", sys_getopt_required_argument, 0, 'p'}, + {"wake-ahead-duration", sys_getopt_required_argument, 0, 'D'}, + {"info-disable", sys_getopt_required_argument, 0, 'd'}, + {"exponent", sys_getopt_required_argument, 0, 'e'}, + {"mantissa", sys_getopt_required_argument, 0, 'm'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, + {"help", sys_getopt_no_argument, 0, 'h'}, {0, 0, 0, 0}}; params->operation = WIFI_TWT_SETUP; - while ((opt = getopt_long(argc, argv, "n:c:t:f:r:T:I:a:t:w:p:D:d:e:m:i:h", + while ((opt = sys_getopt_long(argc, argv, "n:c:t:f:r:T:I:a:t:w:p:D:d:e:m:i:h", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 'n': if (!parse_number(sh, &value, state->optarg, NULL, @@ -2138,22 +2138,22 @@ static int wifi_ap_config_args_to_params(const struct shell *sh, size_t argc, ch { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"max_inactivity", required_argument, 0, 't'}, - {"max_num_sta", required_argument, 0, 's'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"max_inactivity", sys_getopt_required_argument, 0, 't'}, + {"max_num_sta", sys_getopt_required_argument, 0, 's'}, #if defined(CONFIG_WIFI_NM_HOSTAPD_AP) - {"ht_capab", required_argument, 0, 'n'}, - {"vht_capab", required_argument, 0, 'c'}, + {"ht_capab", sys_getopt_required_argument, 0, 'n'}, + {"vht_capab", sys_getopt_required_argument, 0, 'c'}, #endif - {"iface", required_argument, 0, 'i'}, - {"help", no_argument, 0, 'h'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, + {"help", sys_getopt_no_argument, 0, 'h'}, {0, 0, 0, 0}}; long val; - while ((opt = getopt_long(argc, argv, "t:s:n:c:i:h", + while ((opt = sys_getopt_long(argc, argv, "t:s:n:c:i:h", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 't': if (!parse_number(sh, &val, state->optarg, "max_inactivity", @@ -2265,14 +2265,14 @@ static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, bool force = false; bool verbose = false; int opt_index = 0; - static const struct option long_options[] = { - {"force", no_argument, 0, 'f'}, - {"verbose", no_argument, 0, 'v'}, - {"iface", required_argument, 0, 'i'}, + static const struct sys_getopt_option long_options[] = { + {"force", sys_getopt_no_argument, 0, 'f'}, + {"verbose", sys_getopt_no_argument, 0, 'v'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, {NULL, 0, NULL, 0} }; - while ((opt = getopt_long(argc, argv, "fvi:", long_options, &opt_index)) != -1) { + while ((opt = sys_getopt_long(argc, argv, "fvi:", long_options, &opt_index)) != -1) { switch (opt) { case 'f': force = true; @@ -2634,20 +2634,20 @@ void parse_mode_args_to_params(const struct shell *sh, int argc, int opt; int opt_index = 0; int opt_num = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"iface", required_argument, 0, 'i'}, - {"sta", no_argument, 0, 's'}, - {"monitor", no_argument, 0, 'm'}, - {"ap", no_argument, 0, 'a'}, - {"softap", no_argument, 0, 'k'}, - {"help", no_argument, 0, 'h'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"iface", sys_getopt_required_argument, 0, 'i'}, + {"sta", sys_getopt_no_argument, 0, 's'}, + {"monitor", sys_getopt_no_argument, 0, 'm'}, + {"ap", sys_getopt_no_argument, 0, 'a'}, + {"softap", sys_getopt_no_argument, 0, 'k'}, + {"help", sys_getopt_no_argument, 0, 'h'}, {0, 0, 0, 0}}; mode->oper = WIFI_MGMT_GET; - while ((opt = getopt_long(argc, argv, "i:smtpakh", + while ((opt = sys_getopt_long(argc, argv, "i:smtpakh", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 's': mode->mode |= WIFI_STA_MODE; @@ -2737,17 +2737,17 @@ void parse_channel_args_to_params(const struct shell *sh, int argc, { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"iface", optional_argument, 0, 'i'}, - {"channel", required_argument, 0, 'c'}, - {"get", no_argument, 0, 'g'}, - {"help", no_argument, 0, 'h'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"iface", sys_getopt_optional_argument, 0, 'i'}, + {"channel", sys_getopt_required_argument, 0, 'c'}, + {"get", sys_getopt_no_argument, 0, 'g'}, + {"help", sys_getopt_no_argument, 0, 'h'}, {0, 0, 0, 0}}; - while ((opt = getopt_long(argc, argv, "i:c:gh", + while ((opt = sys_getopt_long(argc, argv, "i:c:gh", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 'c': channel->channel = (uint16_t)atoi(state->optarg); @@ -2835,21 +2835,21 @@ void parse_filter_args_to_params(const struct shell *sh, int argc, { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"iface", required_argument, 0, 'i'}, - {"capture-len", optional_argument, 0, 'b'}, - {"all", no_argument, 0, 'a'}, - {"mgmt", no_argument, 0, 'm'}, - {"ctrl", no_argument, 0, 'c'}, - {"data", no_argument, 0, 'd'}, - {"get", no_argument, 0, 'g'}, - {"help", no_argument, 0, 'h'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"iface", sys_getopt_required_argument, 0, 'i'}, + {"capture-len", sys_getopt_optional_argument, 0, 'b'}, + {"all", sys_getopt_no_argument, 0, 'a'}, + {"mgmt", sys_getopt_no_argument, 0, 'm'}, + {"ctrl", sys_getopt_no_argument, 0, 'c'}, + {"data", sys_getopt_no_argument, 0, 'd'}, + {"get", sys_getopt_no_argument, 0, 'g'}, + {"help", sys_getopt_no_argument, 0, 'h'}, {0, 0, 0, 0}}; - while ((opt = getopt_long(argc, argv, "i:b:amcdgh", + while ((opt = sys_getopt_long(argc, argv, "i:b:amcdgh", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 'a': filter->filter |= WIFI_PACKET_FILTER_ALL; @@ -2959,20 +2959,20 @@ static int parse_dpp_args_auth_init(const struct shell *sh, size_t argc, char *a { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"peer", required_argument, 0, 'p'}, - {"role", required_argument, 0, 'r'}, - {"configurator", required_argument, 0, 'c'}, - {"mode", required_argument, 0, 'm'}, - {"ssid", required_argument, 0, 's'}, - {"iface", required_argument, 0, 'i'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"peer", sys_getopt_required_argument, 0, 'p'}, + {"role", sys_getopt_required_argument, 0, 'r'}, + {"configurator", sys_getopt_required_argument, 0, 'c'}, + {"mode", sys_getopt_required_argument, 0, 'm'}, + {"ssid", sys_getopt_required_argument, 0, 's'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, {0, 0, 0, 0}}; int ret = 0; - while ((opt = getopt_long(argc, argv, "p:r:c:m:s:i:", + while ((opt = sys_getopt_long(argc, argv, "p:r:c:m:s:i:", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 'p': params->auth_init.peer = shell_strtol(state->optarg, 10, &ret); @@ -3011,17 +3011,17 @@ static int parse_dpp_args_chirp(const struct shell *sh, size_t argc, char *argv[ { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"own", required_argument, 0, 'o'}, - {"freq", required_argument, 0, 'f'}, - {"iface", required_argument, 0, 'i'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"own", sys_getopt_required_argument, 0, 'o'}, + {"freq", sys_getopt_required_argument, 0, 'f'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, {0, 0, 0, 0}}; int ret = 0; - while ((opt = getopt_long(argc, argv, "o:f:i:", + while ((opt = sys_getopt_long(argc, argv, "o:f:i:", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 'o': params->chirp.id = shell_strtol(state->optarg, 10, &ret); @@ -3051,17 +3051,17 @@ static int parse_dpp_args_listen(const struct shell *sh, size_t argc, char *argv { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"role", required_argument, 0, 'r'}, - {"freq", required_argument, 0, 'f'}, - {"iface", required_argument, 0, 'i'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"role", sys_getopt_required_argument, 0, 'r'}, + {"freq", sys_getopt_required_argument, 0, 'f'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, {0, 0, 0, 0}}; int ret = 0; - while ((opt = getopt_long(argc, argv, "r:f:i:", + while ((opt = sys_getopt_long(argc, argv, "r:f:i:", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 'r': params->listen.role = shell_strtol(state->optarg, 10, &ret); @@ -3091,19 +3091,19 @@ static int parse_dpp_args_btstrap_gen(const struct shell *sh, size_t argc, char { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"type", required_argument, 0, 't'}, - {"opclass", required_argument, 0, 'o'}, - {"channel", required_argument, 0, 'h'}, - {"mac", required_argument, 0, 'a'}, - {"iface", required_argument, 0, 'i'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"type", sys_getopt_required_argument, 0, 't'}, + {"opclass", sys_getopt_required_argument, 0, 'o'}, + {"channel", sys_getopt_required_argument, 0, 'h'}, + {"mac", sys_getopt_required_argument, 0, 'a'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, {0, 0, 0, 0}}; int ret = 0; - while ((opt = getopt_long(argc, argv, "t:o:h:a:i:", + while ((opt = sys_getopt_long(argc, argv, "t:o:h:a:i:", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 't': params->bootstrap_gen.type = shell_strtol(state->optarg, 10, &ret); @@ -3157,18 +3157,18 @@ static int parse_dpp_args_set_config_param(const struct shell *sh, size_t argc, { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"configurator", required_argument, 0, 'c'}, - {"mode", required_argument, 0, 'm'}, - {"ssid", required_argument, 0, 's'}, - {"iface", required_argument, 0, 'i'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"configurator", sys_getopt_required_argument, 0, 'c'}, + {"mode", sys_getopt_required_argument, 0, 'm'}, + {"ssid", sys_getopt_required_argument, 0, 's'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, {0, 0, 0, 0}}; int ret = 0; - while ((opt = getopt_long(argc, argv, "p:r:c:m:s:i:", + while ((opt = sys_getopt_long(argc, argv, "p:r:c:m:s:i:", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 'c': params->configurator_set.configurator = @@ -3449,10 +3449,10 @@ static int cmd_wifi_dpp_ap_auth_init(const struct shell *sh, size_t argc, char * { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"peer", required_argument, 0, 'p'}, - {"iface", required_argument, 0, 'i'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"peer", sys_getopt_required_argument, 0, 'p'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, {0, 0, 0, 0}}; int ret = 0; struct net_if *iface = get_iface(IFACE_TYPE_SAP, argc, argv); @@ -3460,9 +3460,9 @@ static int cmd_wifi_dpp_ap_auth_init(const struct shell *sh, size_t argc, char * params.action = WIFI_DPP_AUTH_INIT; - while ((opt = getopt_long(argc, argv, "p:i:", + while ((opt = sys_getopt_long(argc, argv, "p:i:", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 'p': params.auth_init.peer = shell_strtol(state->optarg, 10, &ret); @@ -3562,20 +3562,21 @@ static int wifi_bgscan_args_to_params(const struct shell *sh, size_t argc, char int err; int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"type", required_argument, 0, 't'}, - {"short-interval", required_argument, 0, 's'}, - {"rss-threshold", required_argument, 0, 'r'}, - {"long-interval", required_argument, 0, 'l'}, - {"btm-queries", required_argument, 0, 'b'}, - {"iface", required_argument, 0, 'i'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"type", sys_getopt_required_argument, 0, 't'}, + {"short-interval", sys_getopt_required_argument, 0, 's'}, + {"rss-threshold", sys_getopt_required_argument, 0, 'r'}, + {"long-interval", sys_getopt_required_argument, 0, 'l'}, + {"btm-queries", sys_getopt_required_argument, 0, 'b'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, {0, 0, 0, 0}}; unsigned long uval; long val; - while ((opt = getopt_long(argc, argv, "t:s:r:l:b:i:", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + while ((opt = sys_getopt_long(argc, argv, "t:s:r:l:b:i:", long_options, + &opt_index)) != -1) { + state = sys_getopt_state_get(); switch (opt) { case 't': if (strcmp("simple", state->optarg) == 0) { @@ -3667,16 +3668,16 @@ static int wifi_config_args_to_params(const struct shell *sh, size_t argc, char { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"okc", required_argument, 0, 'o'}, - {"iface", required_argument, 0, 'i'}, + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"okc", sys_getopt_required_argument, 0, 'o'}, + {"iface", sys_getopt_required_argument, 0, 'i'}, {0, 0, 0, 0}}; long val; - while ((opt = getopt_long(argc, argv, "o:i:", + while ((opt = sys_getopt_long(argc, argv, "o:i:", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + state = sys_getopt_state_get(); switch (opt) { case 'o': if (!parse_number(sh, &val, state->optarg, "okc", 0, 1)) { diff --git a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c index 3966a2404bcb8..7f2402120c9bf 100644 --- a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c +++ b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c @@ -117,14 +117,19 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) { int opt; int opt_index = 0; - struct getopt_state *state; - static const struct option long_options[] = { - {"ssid", required_argument, 0, 's'}, {"passphrase", required_argument, 0, 'p'}, - {"key-mgmt", required_argument, 0, 'k'}, {"ieee-80211w", required_argument, 0, 'w'}, - {"bssid", required_argument, 0, 'm'}, {"band", required_argument, 0, 'b'}, - {"channel", required_argument, 0, 'c'}, {"timeout", required_argument, 0, 't'}, - {"identity", required_argument, 0, 'a'}, {"key-passwd", required_argument, 0, 'K'}, - {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; + struct sys_getopt_state *state; + static const struct sys_getopt_option long_options[] = { + {"ssid", sys_getopt_required_argument, 0, 's'}, + {"passphrase", sys_getopt_required_argument, 0, 'p'}, + {"key-mgmt", sys_getopt_required_argument, 0, 'k'}, + {"ieee-80211w", sys_getopt_required_argument, 0, 'w'}, + {"bssid", sys_getopt_required_argument, 0, 'm'}, + {"band", sys_getopt_required_argument, 0, 'b'}, + {"channel", sys_getopt_required_argument, 0, 'c'}, + {"timeout", sys_getopt_required_argument, 0, 't'}, + {"identity", sys_getopt_required_argument, 0, 'a'}, + {"key-passwd", sys_getopt_required_argument, 0, 'K'}, + {"help", sys_getopt_no_argument, 0, 'h'}, {0, 0, 0, 0}}; char *endptr; bool secure_connection = false; uint8_t band; @@ -138,9 +143,9 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) long channel; long mfp = WIFI_MFP_OPTIONAL; - while ((opt = getopt_long(argc, argv, "s:p:k:w:b:c:m:t:a:K:h", long_options, &opt_index)) != - -1) { - state = getopt_state_get(); + while ((opt = sys_getopt_long(argc, argv, "s:p:k:w:b:c:m:t:a:K:h", + long_options, &opt_index)) != -1) { + state = sys_getopt_state_get(); switch (opt) { case 's': creds.header.ssid_len = strlen(state->optarg); diff --git a/subsys/shell/Kconfig b/subsys/shell/Kconfig index c35b0193f6b4b..2f5e1e0729fe5 100644 --- a/subsys/shell/Kconfig +++ b/subsys/shell/Kconfig @@ -190,11 +190,11 @@ config SHELL_VT100_COLORS config SHELL_GETOPT bool "Threadsafe getopt support in shell" - select POSIX_C_LIB_EXT + select GETOPT help This config creates a separate getopt_state for the shell instance. It ensures that using getopt with shell is thread safe. - When more threads are using getopt please call getopt_state_get to + When more threads are using sys_getopt please call sys_getopt_state_get to get getopt state of the shell thread. config SHELL_METAKEYS diff --git a/subsys/shell/modules/Kconfig b/subsys/shell/modules/Kconfig index b4d904fb474c3..cb6c560e0c4f4 100644 --- a/subsys/shell/modules/Kconfig +++ b/subsys/shell/modules/Kconfig @@ -29,7 +29,7 @@ config DATE_SHELL config DEVMEM_SHELL bool "Devmem shell" default y if !SHELL_MINIMAL - select POSIX_C_LIB_EXT + select GETOPT help This shell command provides read/write access to physical memory. diff --git a/subsys/shell/modules/devmem_service.c b/subsys/shell/modules/devmem_service.c index d54f2d14c13d3..1e4932ae10039 100644 --- a/subsys/shell/modules/devmem_service.c +++ b/subsys/shell/modules/devmem_service.c @@ -10,20 +10,12 @@ #define _POSIX_C_SOURCE 200809L #include -#ifdef CONFIG_NATIVE_LIBC -#include -#else -#include -#endif +#include #include #include #include #include -#ifndef CONFIG_NATIVE_LIBC -extern void getopt_init(void); -#endif - static inline bool is_ascii(uint8_t data) { return (data >= 0x30 && data <= 0x39) || (data >= 0x61 && data <= 0x66) || @@ -122,30 +114,29 @@ static int cmd_dump(const struct shell *sh, size_t argc, char **argv) size_t width = 32; mem_addr_t addr = -1; - optind = 1; -#ifndef CONFIG_NATIVE_LIBC - getopt_init(); -#endif - while ((rv = getopt(argc, argv, "a:s:w:")) != -1) { + sys_getopt_optind = 1; + sys_getopt_init(); + + while ((rv = sys_getopt(argc, argv, "a:s:w:")) != -1) { switch (rv) { case 'a': - addr = (mem_addr_t)shell_strtoul(optarg, 16, &err); + addr = (mem_addr_t)shell_strtoul(sys_getopt_optarg, 16, &err); if (err != 0) { - shell_error(sh, "invalid addr '%s'", optarg); + shell_error(sh, "invalid addr '%s'", sys_getopt_optarg); return -EINVAL; } break; case 's': - size = (size_t)shell_strtoul(optarg, 0, &err); + size = (size_t)shell_strtoul(sys_getopt_optarg, 0, &err); if (err != 0) { - shell_error(sh, "invalid size '%s'", optarg); + shell_error(sh, "invalid size '%s'", sys_getopt_optarg); return -EINVAL; } break; case 'w': - width = (size_t)shell_strtoul(optarg, 0, &err); + width = (size_t)shell_strtoul(sys_getopt_optarg, 0, &err); if (err != 0) { - shell_error(sh, "invalid width '%s'", optarg); + shell_error(sh, "invalid width '%s'", sys_getopt_optarg); return -EINVAL; } break; diff --git a/subsys/shell/modules/kernel_service/uptime.c b/subsys/shell/modules/kernel_service/uptime.c index c00f4f1607153..c4257be1fe455 100644 --- a/subsys/shell/modules/kernel_service/uptime.c +++ b/subsys/shell/modules/kernel_service/uptime.c @@ -26,7 +26,7 @@ static int cmd_kernel_uptime(const struct shell *sh, size_t argc, char **argv) return 0; } - /* No need to enable the getopt and getopt_long for just one option. */ + /* No need to enable the sys_getopt and sys_getopt_long for just one option. */ if (strcmp("-p", argv[1]) && strcmp("--pretty", argv[1]) != 0) { shell_error(sh, "Unsupported option: %s", argv[1]); return -EIO; diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index 8c3380d23ba6d..c073489973fa1 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -546,7 +546,7 @@ static int exec_cmd(const struct shell *sh, size_t argc, const char **argv, if (!ret_val) { #if CONFIG_SHELL_GETOPT - getopt_init(); + sys_getopt_init(); #endif z_flag_cmd_ctx_set(sh, true); diff --git a/subsys/testsuite/ztest/src/ztest.c b/subsys/testsuite/ztest/src/ztest.c index 080e172652845..28653d06aebb3 100644 --- a/subsys/testsuite/ztest/src/ztest.c +++ b/subsys/testsuite/ztest/src/ztest.c @@ -1253,11 +1253,12 @@ static int cmd_runall(const struct shell *sh, size_t argc, char **argv) static int cmd_shuffle(const struct shell *sh, size_t argc, char **argv) { - struct getopt_state *state; + struct sys_getopt_state *state; int opt; - static struct option long_options[] = {{"suite_iter", required_argument, 0, 's'}, - {"case_iter", required_argument, 0, 'c'}, - {0, 0, 0, 0}}; + static struct sys_getopt_option long_options[] = { + {"suite_iter", sys_getopt_required_argument, 0, 's'}, + {"case_iter", sys_getopt_required_argument, 0, 'c'}, + {0, 0, 0, 0}}; int opt_index = 0; int val; int opt_num = 0; @@ -1265,8 +1266,8 @@ static int cmd_shuffle(const struct shell *sh, size_t argc, char **argv) int suite_iter = 1; int case_iter = 1; - while ((opt = getopt_long(argc, argv, "s:c:", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + while ((opt = sys_getopt_long(argc, argv, "s:c:", long_options, &opt_index)) != -1) { + state = sys_getopt_state_get(); switch (opt) { case 's': val = atoi(state->optarg); @@ -1301,9 +1302,10 @@ static int cmd_shuffle(const struct shell *sh, size_t argc, char **argv) static int cmd_run_suite(const struct shell *sh, size_t argc, char **argv) { - struct getopt_state *state; + struct sys_getopt_state *state; int opt; - static struct option long_options[] = {{"repeat_iter", required_argument, NULL, 'r'}, + static struct sys_getopt_option long_options[] = { + {"repeat_iter", sys_getopt_required_argument, NULL, 'r'}, {NULL, 0, NULL, 0}}; int opt_index = 0; int val; @@ -1311,8 +1313,8 @@ static int cmd_run_suite(const struct shell *sh, size_t argc, char **argv) void *param = NULL; int repeat_iter = 1; - while ((opt = getopt_long(argc, argv, "r:p:", long_options, &opt_index)) != -1) { - state = getopt_state_get(); + while ((opt = sys_getopt_long(argc, argv, "r:p:", long_options, &opt_index)) != -1) { + state = sys_getopt_state_get(); switch (opt) { case 'r': val = atoi(state->optarg); From d87cc4e993f111d3b6667461b61265e1e210fb17 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 4 Nov 2025 14:04:02 +0200 Subject: [PATCH 2/2] lib: posix: Add shim for getopt API Allow user to use the new sys_getopt API via the old non-Posix compliant getopt API. This is a temporary solution and the shim will be deprecated and eventually removed at some point. Signed-off-by: Jukka Rissanen (cherry picked from commit d164f8b55d08aba8084fcd5e0d3bce93263f1aa3) --- lib/posix/c_lib_ext/CMakeLists.txt | 1 + lib/posix/c_lib_ext/Kconfig | 1 + lib/posix/c_lib_ext/getopt/getopt.h | 37 ++++++++++++++++++++++ lib/posix/c_lib_ext/getopt_shim.c | 47 ++++++++++++++++++++++++++++ lib/utils/getopt/getopt_common.c | 10 ++++++ tests/posix/c_lib_ext/CMakeLists.txt | 2 +- 6 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 lib/posix/c_lib_ext/getopt/getopt.h create mode 100644 lib/posix/c_lib_ext/getopt_shim.c diff --git a/lib/posix/c_lib_ext/CMakeLists.txt b/lib/posix/c_lib_ext/CMakeLists.txt index 46923199e61f4..374a2533d557b 100644 --- a/lib/posix/c_lib_ext/CMakeLists.txt +++ b/lib/posix/c_lib_ext/CMakeLists.txt @@ -10,4 +10,5 @@ zephyr_library() zephyr_library_sources( fnmatch.c getentropy.c + getopt_shim.c ) diff --git a/lib/posix/c_lib_ext/Kconfig b/lib/posix/c_lib_ext/Kconfig index 8c9751d0914bd..baa77e84a8b4b 100644 --- a/lib/posix/c_lib_ext/Kconfig +++ b/lib/posix/c_lib_ext/Kconfig @@ -4,6 +4,7 @@ config POSIX_C_LIB_EXT bool "POSIX general C library extension" + select GETOPT help Select 'y' here and Zephyr will provide an implementation of the POSIX_C_LIB_EXT Option Group, consisting of fnmatch(), getopt(), getsubopt(), optarg, opterr, optind, optopt, diff --git a/lib/posix/c_lib_ext/getopt/getopt.h b/lib/posix/c_lib_ext/getopt/getopt.h new file mode 100644 index 0000000000000..02a9593df0103 --- /dev/null +++ b/lib/posix/c_lib_ext/getopt/getopt.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern void getopt_init(void); + +#define getopt_state sys_getopt_state +#define option sys_getopt_option + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +extern struct sys_getopt_state *getopt_state_get(void); + +extern int getopt_long(int nargc, char *const *nargv, const char *options, + const struct option *long_options, int *idx); + +extern int getopt_long_only(int nargc, char *const *nargv, const char *options, + const struct option *long_options, int *idx); + +#ifdef __cplusplus +} +#endif + +#endif /* _GETOPT_H_ */ diff --git a/lib/posix/c_lib_ext/getopt_shim.c b/lib/posix/c_lib_ext/getopt_shim.c new file mode 100644 index 0000000000000..1187c53440ab7 --- /dev/null +++ b/lib/posix/c_lib_ext/getopt_shim.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "getopt.h" + +char *optarg; +int opterr, optind, optopt; + +void getopt_init(void) +{ + sys_getopt_init(); +} + +struct getopt_state *getopt_state_get(void) +{ + return sys_getopt_state_get(); +} + +int getopt(int argc, char *const argv[], const char *optstring) +{ + return sys_getopt(argc, argv, optstring); +} + +void z_getopt_global_state_update_shim(struct sys_getopt_state *state) +{ + opterr = state->opterr; + optind = state->optind; + optopt = state->optopt; + optarg = state->optarg; +} + +int getopt_long(int argc, char *const argv[], const char *shortopts, + const struct option *longopts, int *longind) +{ + return sys_getopt_long(argc, argv, shortopts, longopts, longind); +} + +int getopt_long_only(int argc, char *const argv[], const char *shortopts, + const struct option *longopts, int *longind) +{ + return sys_getopt_long_only(argc, argv, shortopts, longopts, longind); +} diff --git a/lib/utils/getopt/getopt_common.c b/lib/utils/getopt/getopt_common.c index bfc3d8d8fc2d4..a5d58e9576077 100644 --- a/lib/utils/getopt/getopt_common.c +++ b/lib/utils/getopt/getopt_common.c @@ -38,6 +38,12 @@ static struct sys_getopt_state m_getopt_common_state = { #endif }; +/* Shim function to update global variables in getopt_shim.c if user wants to + * still use the original non-posix compliant getopt. The shim will be deprecated + * and eventually removed in the future. + */ +extern void z_getopt_global_state_update_shim(struct sys_getopt_state *state); + /* This function is not thread safe. All threads using getopt are calling * this function. */ @@ -48,6 +54,10 @@ void z_getopt_global_state_update(struct sys_getopt_state *state) sys_getopt_optopt = state->optopt; sys_getopt_optreset = state->optreset; sys_getopt_optarg = state->optarg; + + if (!IS_ENABLED(CONFIG_NATIVE_LIBC) && IS_ENABLED(CONFIG_POSIX_C_LIB_EXT)) { + z_getopt_global_state_update_shim(state); + } } /* It is internal getopt API function, it shall not be called by the user. */ diff --git a/tests/posix/c_lib_ext/CMakeLists.txt b/tests/posix/c_lib_ext/CMakeLists.txt index 24c7cfd219486..0e7bfa6f052e9 100644 --- a/tests/posix/c_lib_ext/CMakeLists.txt +++ b/tests/posix/c_lib_ext/CMakeLists.txt @@ -8,5 +8,5 @@ FILE(GLOB app_sources src/*.c) target_sources(app PRIVATE ${app_sources}) -target_include_directories(app PRIVATE ${ZEPHYR_BASE}/lib/posix/options/getopt) +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/lib/posix/c_lib_ext/getopt) target_compile_options(app PRIVATE -U_POSIX_C_SOURCE -D_POSIX_C_SOURCE=200809L)