diff --git a/doc/services/shell/index.rst b/doc/services/shell/index.rst index d259f453cfa8b..1d6c16d163881 100644 --- a/doc/services/shell/index.rst +++ b/doc/services/shell/index.rst @@ -686,12 +686,12 @@ the arguments string, looking for supported options. Typically, this task is accomplished by the ``getopt`` family functions. 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: +the FreeBSD project called sys_getopt_r and sys_getopt_long_r. 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. -The former is full compatible with regular getopt usage while the latter +This feature can be used in non thread safe as well as thread safe manner. +The former is fully compatible with regular getopt usage while the latter a bit differs. An example non-thread safe usage: @@ -714,21 +714,17 @@ An example thread safe usage: .. code-block:: c char *cvalue = NULL; - struct sys_getopt_state *state; - while ((char c = sys_getopt(argc, argv, "abhc:")) != -1) { - state = sys_getopt_state_get(); + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; + while ((char c = sys_getopt_r(argc, argv, "abhc:", &state)) != -1) { switch (c) { case 'c': - cvalue = state->optarg; + cvalue = state.optarg; break; default: break; } } -Thread safe sys_getopt functionality is activated by -:kconfig:option:`CONFIG_SHELL_GETOPT` set to ``y``. - Obscured Input Feature ********************** diff --git a/include/zephyr/sys/sys_getopt.h b/include/zephyr/sys/sys_getopt.h index 7ffaf248f23cb..474375f87e5da 100644 --- a/include/zephyr/sys/sys_getopt.h +++ b/include/zephyr/sys/sys_getopt.h @@ -34,6 +34,9 @@ extern int sys_getopt_opterr; extern int sys_getopt_optind; extern int sys_getopt_optopt; +/* Initialize local sys_getopt_state with this value */ +#define SYS_GETOPT_STATE_INITIALIZER {0} + #define sys_getopt_no_argument 0 #define sys_getopt_required_argument 1 #define sys_getopt_optional_argument 2 @@ -52,6 +55,9 @@ struct sys_getopt_option { int val; }; +/* Function initializes getopt_state structure */ +void sys_getopt_init_r(struct sys_getopt_state *state); + /* Function initializes getopt_state structure for current thread */ void sys_getopt_init(void); @@ -67,16 +73,19 @@ struct sys_getopt_state *sys_getopt_state_get(void); * @param[in] nargc Arguments count. * @param[in] nargv Arguments. * @param[in] ostr String containing the legitimate option characters. + * @param[inout] state Current argument parsing state. * * @return If an option was successfully found, function returns * the option character. */ +int sys_getopt_r(int nargc, char *const nargv[], const char *ostr, struct sys_getopt_state *state); + 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 + * The sys_getopt_long_r() function works like @ref sys_getopt_r() except * it also accepts long options, started with two dashes. * * @note This function is based on FreeBSD implementation but it does not @@ -90,17 +99,22 @@ int sys_getopt(int nargc, char *const nargv[], const char *ostr); * @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. + * @param[inout] state Current argument parsing state. * * @return If an option was successfully found, function returns * the option character. */ +int sys_getopt_long_r(int nargc, char *const *nargv, const char *options, + const struct sys_getopt_option *long_options, int *idx, + struct sys_getopt_state *state); + 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 sys_getopt_long_only() function works like @ref sys_getopt_long(), + * The sys_getopt_long_only_r() function works like @ref sys_getopt_long_r(), * 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. @@ -116,10 +130,15 @@ int sys_getopt_long(int nargc, char *const *nargv, const char *options, * @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. + * @param[inout] state Current argument parsing state. * * @return If an option was successfully found, function returns * the option character. */ +int sys_getopt_long_only_r(int nargc, char *const *nargv, const char *options, + const struct sys_getopt_option *long_options, int *idx, + struct sys_getopt_state *state); + int sys_getopt_long_only(int nargc, char *const *nargv, const char *options, const struct sys_getopt_option *long_options, int *idx); diff --git a/lib/posix/c_lib_ext/getopt/getopt.h b/lib/posix/c_lib_ext/getopt/getopt.h index 02a9593df0103..09134bc176f31 100644 --- a/lib/posix/c_lib_ext/getopt/getopt.h +++ b/lib/posix/c_lib_ext/getopt/getopt.h @@ -13,17 +13,12 @@ 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); diff --git a/lib/posix/c_lib_ext/getopt_shim.c b/lib/posix/c_lib_ext/getopt_shim.c index 1187c53440ab7..b773ad532e252 100644 --- a/lib/posix/c_lib_ext/getopt_shim.c +++ b/lib/posix/c_lib_ext/getopt_shim.c @@ -11,37 +11,52 @@ char *optarg; int opterr, optind, optopt; -void getopt_init(void) +static struct sys_getopt_state getopt_state = SYS_GETOPT_STATE_INITIALIZER; + +static void getopt_global_state_get(void) { - sys_getopt_init(); + getopt_state.opterr = opterr; + getopt_state.optind = optind; + getopt_state.optopt = optopt; + getopt_state.optarg = optarg; } -struct getopt_state *getopt_state_get(void) +static void getopt_global_state_put(void) { - return sys_getopt_state_get(); + opterr = getopt_state.opterr; + optind = getopt_state.optind; + optopt = getopt_state.optopt; + optarg = getopt_state.optarg; } int getopt(int argc, char *const argv[], const char *optstring) { - return sys_getopt(argc, argv, optstring); -} + int ret; -void z_getopt_global_state_update_shim(struct sys_getopt_state *state) -{ - opterr = state->opterr; - optind = state->optind; - optopt = state->optopt; - optarg = state->optarg; + getopt_global_state_get(); + ret = sys_getopt_r(argc, argv, optstring, &getopt_state); + getopt_global_state_put(); + return ret; } 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 ret; + + getopt_global_state_get(); + ret = sys_getopt_long_r(argc, argv, shortopts, longopts, longind, &getopt_state); + getopt_global_state_put(); + return ret; } 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); + int ret; + + getopt_global_state_get(); + ret = sys_getopt_long_only_r(argc, argv, shortopts, longopts, longind, &getopt_state); + getopt_global_state_put(); + return ret; } diff --git a/lib/posix/shell/uname.c b/lib/posix/shell/uname.c index 176a28504a54b..a4edd606c1fc2 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 sys_getopt_state *state = sys_getopt_state_get(); + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; struct utsname info; unsigned int set; int option; @@ -53,8 +53,7 @@ static int uname_cmd_handler(const struct shell *sh, size_t argc, char **argv) /* Get the uname options */ - optind = 1; - while ((option = sys_getopt(argc, argv, "asonrvmpi")) != -1) { + while ((option = sys_getopt_r(argc, argv, "asonrvmpi", &state)) != -1) { switch (option) { case 'a': set = UNAME_ALL; @@ -93,13 +92,13 @@ static int uname_cmd_handler(const struct shell *sh, size_t argc, char **argv) case '?': default: - badarg = (char)state->optopt; + badarg = (char)state.optopt; break; } } - if (argc != optind) { - shell_error(sh, "uname: extra operand %s", argv[optind]); + if (argc != state.optind) { + shell_error(sh, "uname: extra operand %s", argv[state.optind]); uname_print_usage(sh); return -1; } diff --git a/lib/utils/getopt/getopt.c b/lib/utils/getopt/getopt.c index ceb600e10f4aa..959ba8dafc667 100644 --- a/lib/utils/getopt/getopt.c +++ b/lib/utils/getopt/getopt.c @@ -40,12 +40,8 @@ LOG_MODULE_REGISTER(sys_getopt); #define BADARG ((int)':') #define EMSG "" -void sys_getopt_init(void) +void sys_getopt_init_r(struct sys_getopt_state *state) { - struct sys_getopt_state *state; - - state = sys_getopt_state_get(); - state->opterr = 1; state->optind = 1; state->optopt = 0; @@ -58,25 +54,30 @@ void sys_getopt_init(void) state->nonopt_start = -1; /* first non option argument (for permute) */ state->nonopt_end = -1; /* first option after non options (for permute) */ #endif +} - sys_getopt_opterr = 1; - sys_getopt_optind = 1; - sys_getopt_optopt = 0; - sys_getopt_optreset = 0; - sys_getopt_optarg = NULL; +void sys_getopt_init(void) +{ + struct sys_getopt_state *state; + + state = sys_getopt_state_get(); + + sys_getopt_init_r(state); + z_getopt_global_state_update(state); } /* * getopt -- * Parse argc/argv argument vector. */ -int sys_getopt(int nargc, char *const nargv[], const char *ostr) +int sys_getopt_r(int nargc, char *const nargv[], const char *ostr, struct sys_getopt_state *state) { - struct sys_getopt_state *state; char *oli; /* option letter list index */ - /* get getopt state of the current thread */ - state = sys_getopt_state_get(); + /* Reset if optind is 0 */ + if (state->optind == 0) { + sys_getopt_init_r(state); + } if (state->optreset || *state->place == 0) { /* update scanning pointer */ state->optreset = 0; @@ -84,7 +85,6 @@ int sys_getopt(int nargc, char *const nargv[], const char *ostr) if (state->optind >= nargc || *state->place++ != '-') { /* Argument is absent or is not an option */ state->place = EMSG; - z_getopt_global_state_update(state); return -1; } state->optopt = *state->place++; @@ -92,7 +92,6 @@ int sys_getopt(int nargc, char *const nargv[], const char *ostr) /* "--" => end of options */ ++state->optind; state->place = EMSG; - z_getopt_global_state_update(state); return -1; } if (state->optopt == 0) { @@ -101,7 +100,6 @@ int sys_getopt(int nargc, char *const nargv[], const char *ostr) */ state->place = EMSG; if (strchr(ostr, '-') == NULL) { - z_getopt_global_state_update(state); return -1; } state->optopt = '-'; @@ -119,7 +117,6 @@ int sys_getopt(int nargc, char *const nargv[], const char *ostr) if (state->opterr && *ostr != ':') { LOG_DBG("illegal option -- %c", state->optopt); } - z_getopt_global_state_update(state); return BADCH; } @@ -142,18 +139,32 @@ int sys_getopt(int nargc, char *const nargv[], const char *ostr) /* option-argument absent */ state->place = EMSG; if (*ostr == ':') { - z_getopt_global_state_update(state); return BADARG; } if (state->opterr) { LOG_DBG("option requires an argument -- %c", state->optopt); } - z_getopt_global_state_update(state); return BADCH; } state->place = EMSG; ++state->optind; } - z_getopt_global_state_update(state); return state->optopt; /* return option letter */ } + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int sys_getopt(int nargc, char *const nargv[], const char *ostr) +{ + struct sys_getopt_state *state; + int ret; + + /* Get state of the current thread */ + state = sys_getopt_state_get(); + ret = sys_getopt_r(nargc, nargv, ostr, state); + + z_getopt_global_state_update(state); + return ret; +} diff --git a/lib/utils/getopt/getopt_common.c b/lib/utils/getopt/getopt_common.c index a5d58e9576077..bfc3d8d8fc2d4 100644 --- a/lib/utils/getopt/getopt_common.c +++ b/lib/utils/getopt/getopt_common.c @@ -38,12 +38,6 @@ 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. */ @@ -54,10 +48,6 @@ 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/lib/utils/getopt/getopt_long.c b/lib/utils/getopt/getopt_long.c index e936c9f1eed5d..6295805befaf6 100644 --- a/lib/utils/getopt/getopt_long.c +++ b/lib/utils/getopt/getopt_long.c @@ -348,6 +348,11 @@ static int getopt_internal(struct sys_getopt_state *state, int nargc, char *cons return -1; } + /* Reset if optind is 0 */ + if (state->optind == 0) { + sys_getopt_init_r(state); + } + /* * Disable GNU extensions if options string begins with a '+'. */ @@ -368,14 +373,6 @@ static int getopt_internal(struct sys_getopt_state *state, int nargc, char *cons options++; } - /* - * XXX Some GNU programs (like cvs) set optind to 0 instead of - * XXX using optreset. Work around this braindamage. - */ - if (state->optind == 0) { - state->optind = state->optreset = 1; - } - state->optarg = NULL; if (state->optreset) { state->nonopt_start = state->nonopt_end = -1; @@ -568,6 +565,13 @@ static int getopt_internal(struct sys_getopt_state *state, int nargc, char *cons * getopt_long -- * Parse argc/argv argument vector. */ +int sys_getopt_long_r(int nargc, char *const *nargv, const char *options, + const struct sys_getopt_option *long_options, int *idx, + struct sys_getopt_state *state) +{ + return getopt_internal(state, nargc, nargv, options, long_options, idx, FLAG_PERMUTE); +} + int sys_getopt_long(int nargc, char *const *nargv, const char *options, const struct sys_getopt_option *long_options, int *idx) { @@ -588,6 +592,14 @@ int sys_getopt_long(int nargc, char *const *nargv, const char *options, * getopt_long_only -- * Parse argc/argv argument vector. */ +int sys_getopt_long_only_r(int nargc, char *const *nargv, const char *options, + const struct sys_getopt_option *long_options, int *idx, + struct sys_getopt_state *state) +{ + return getopt_internal(state, nargc, nargv, options, long_options, idx, + FLAG_PERMUTE | FLAG_LONGONLY); +} + int sys_getopt_long_only(int nargc, char *const *nargv, const char *options, const struct sys_getopt_option *long_options, int *idx) { diff --git a/samples/shields/npm6001_ek/src/main.c b/samples/shields/npm6001_ek/src/main.c index f73e391083082..963209e5cd029 100644 --- a/samples/shields/npm6001_ek/src/main.c +++ b/samples/shields/npm6001_ek/src/main.c @@ -15,8 +15,6 @@ #include #include -#include - struct regulators_map { const char *name; const struct device *dev; @@ -312,27 +310,29 @@ static int cmd_gpio_configure(const struct shell *sh, size_t argc, char **argv) {NULL, 0, NULL, 0}, }; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; + high_drive = 0; pull_down = 0; cmos = 0; - while ((opt = sys_getopt_long(argc, argv, "p:d:", long_options, - &long_index)) != -1) { + while ((opt = sys_getopt_long_r(argc, argv, "p:d:", long_options, + &long_index, &state)) != -1) { switch (opt) { case 0: /* options setting a flag, do nothing */ break; case 'p': - pin = atoi(sys_getopt_optarg); + pin = atoi(state.optarg); break; case 'd': - if (strcmp(sys_getopt_optarg, "in") == 0) { + if (strcmp(state.optarg, "in") == 0) { flags |= GPIO_INPUT; - } else if (strcmp(sys_getopt_optarg, "out") == 0) { + } else if (strcmp(state.optarg, "out") == 0) { flags |= GPIO_OUTPUT; - } else if (strcmp(sys_getopt_optarg, "outh") == 0) { + } else if (strcmp(state.optarg, "outh") == 0) { flags |= GPIO_OUTPUT_HIGH; - } else if (strcmp(sys_getopt_optarg, "outl") == 0) { + } else if (strcmp(state.optarg, "outl") == 0) { flags |= GPIO_OUTPUT_LOW; } break; diff --git a/samples/subsys/shell/shell_module/src/main.c b/samples/subsys/shell/shell_module/src/main.c index 97297b11e10b7..98c8b2ae995df 100644 --- a/samples/subsys/shell/shell_module/src/main.c +++ b/samples/subsys/shell/shell_module/src/main.c @@ -12,12 +12,6 @@ #include #include -#ifdef CONFIG_NATIVE_LIBC -#include -#else -#include -#endif - LOG_MODULE_REGISTER(app); extern void foo(void); @@ -109,14 +103,13 @@ 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 sys_getopt_state *state; char *cvalue = NULL; int aflag = 0; int bflag = 0; int c; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; - while ((c = sys_getopt(argc, argv, "abhc:")) != -1) { - state = sys_getopt_state_get(); + while ((c = sys_getopt_r(argc, argv, "abhc:", &state)) != -1) { switch (c) { case 'a': aflag = 1; @@ -125,7 +118,7 @@ static int cmd_demo_getopt_ts(const struct shell *sh, size_t argc, bflag = 1; break; case 'c': - cvalue = state->optarg; + cvalue = state.optarg; break; case 'h': /* When getopt is active shell is not parsing @@ -135,18 +128,18 @@ static int cmd_demo_getopt_ts(const struct shell *sh, size_t argc, shell_help(sh); return SHELL_CMD_HELP_PRINTED; case '?': - if (state->optopt == 'c') { + if (state.optopt == 'c') { shell_print(sh, "Option -%c requires an argument.", - state->optopt); - } else if (isprint(state->optopt) != 0) { + state.optopt); + } else if (isprint(state.optopt) != 0) { shell_print(sh, "Unknown option `-%c'.", - state->optopt); + state.optopt); } else { shell_print(sh, "Unknown option character `\\x%x'.", - state->optopt); + state.optopt); } return 1; default: @@ -165,8 +158,9 @@ static int cmd_demo_getopt(const struct shell *sh, size_t argc, int aflag = 0; int bflag = 0; int c; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; - while ((c = sys_getopt(argc, argv, "abhc:")) != -1) { + while ((c = sys_getopt_r(argc, argv, "abhc:", &state)) != -1) { switch (c) { case 'a': aflag = 1; @@ -175,7 +169,7 @@ static int cmd_demo_getopt(const struct shell *sh, size_t argc, bflag = 1; break; case 'c': - cvalue = sys_getopt_optarg; + cvalue = state.optarg; break; case 'h': /* When getopt is active shell is not parsing @@ -185,17 +179,17 @@ static int cmd_demo_getopt(const struct shell *sh, size_t argc, shell_help(sh); return SHELL_CMD_HELP_PRINTED; case '?': - if (sys_getopt_optopt == 'c') { + if (state.optopt == 'c') { shell_print(sh, "Option -%c requires an argument.", - sys_getopt_optopt); - } else if (isprint(sys_getopt_optopt) != 0) { + state.optopt); + } else if (isprint(state.optopt) != 0) { shell_print(sh, "Unknown option `-%c'.", - sys_getopt_optopt); + state.optopt); } else { shell_print(sh, "Unknown option character `\\x%x'.", - sys_getopt_optopt); + state.optopt); } return 1; default: diff --git a/subsys/crc/crc_shell.c b/subsys/crc/crc_shell.c index b8c313403de06..976a5d8d89a1c 100644 --- a/subsys/crc/crc_shell.c +++ b/subsys/crc/crc_shell.c @@ -8,11 +8,6 @@ #include #include #include -#ifdef CONFIG_NATIVE_LIBC -#include -#else -#include -#endif #include #include @@ -79,9 +74,9 @@ static int cmd_crc(const struct shell *sh, size_t argc, char **argv) void *addr = (void *)-1; enum crc_type type = CRC32_IEEE; - sys_getopt_optind = 1; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; - while ((rv = sys_getopt(argc, argv, "fhlp:rs:t:")) != -1) { + while ((rv = sys_getopt_r(argc, argv, "fhlp:rs:t:", &state)) != -1) { switch (rv) { case 'f': first = true; @@ -93,9 +88,9 @@ static int cmd_crc(const struct shell *sh, size_t argc, char **argv) last = true; break; case 'p': - poly = (size_t)strtoul(sys_getopt_optarg, NULL, 16); + poly = (size_t)strtoul(state.optarg, NULL, 16); if (poly == 0 && errno == EINVAL) { - shell_error(sh, "invalid seed '%s'", sys_getopt_optarg); + shell_error(sh, "invalid seed '%s'", state.optarg); return -EINVAL; } break; @@ -103,16 +98,16 @@ static int cmd_crc(const struct shell *sh, size_t argc, char **argv) reflect = true; break; case 's': - seed = (size_t)strtoul(sys_getopt_optarg, NULL, 16); + seed = (size_t)strtoul(state.optarg, NULL, 16); if (seed == 0 && errno == EINVAL) { - shell_error(sh, "invalid seed '%s'", sys_getopt_optarg); + shell_error(sh, "invalid seed '%s'", state.optarg); return -EINVAL; } break; case 't': - type = string_to_crc_type(sys_getopt_optarg); + type = string_to_crc_type(state.optarg); if (type == -1) { - shell_error(sh, "invalid type '%s'", sys_getopt_optarg); + shell_error(sh, "invalid type '%s'", state.optarg); return -EINVAL; } break; @@ -123,21 +118,21 @@ static int cmd_crc(const struct shell *sh, size_t argc, char **argv) } } - if (sys_getopt_optind + 2 > argc) { + if (state.optind + 2 > argc) { shell_error(sh, "'address' and 'size' arguments are mandatory"); usage(sh); return -EINVAL; } - addr = (void *)strtoul(argv[sys_getopt_optind], NULL, 16); + addr = (void *)strtoul(argv[state.optind], NULL, 16); if (addr == 0 && errno == EINVAL) { - shell_error(sh, "invalid address '%s'", argv[sys_getopt_optind]); + shell_error(sh, "invalid address '%s'", argv[state.optind]); return -EINVAL; } - size = (size_t)strtoul(argv[sys_getopt_optind + 1], NULL, 0); + size = (size_t)strtoul(argv[state.optind + 1], NULL, 0); if (size == 0 && errno == EINVAL) { - shell_error(sh, "invalid size '%s'", argv[sys_getopt_optind + 1]); + shell_error(sh, "invalid size '%s'", argv[state.optind + 1]); return -EINVAL; } diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 323507de031fc..2510e5ef1f30a 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -582,7 +582,7 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"ssid", sys_getopt_required_argument, 0, 's'}, {"passphrase", sys_getopt_required_argument, 0, 'p'}, @@ -649,12 +649,11 @@ 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 = 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 = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(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, &state)) != -1) { switch (opt) { case 's': - params->ssid = state->optarg; + params->ssid = state.optarg; params->ssid_length = strlen(params->ssid); if (params->ssid_length > WIFI_SSID_MAX_LEN) { PR_WARNING("SSID too long (max %d characters)\n", @@ -663,17 +662,17 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv } break; case 'k': - params->security = atoi(state->optarg); + params->security = atoi(state.optarg); if (params->security) { secure_connection = true; } break; case 'p': - params->psk = state->optarg; + params->psk = state.optarg; params->psk_length = strlen(params->psk); break; case 'c': - channel = strtol(state->optarg, &endptr, 10); + channel = strtol(state.optarg, &endptr, 10); if (iface_mode == WIFI_MODE_AP && channel == 0) { params->channel = channel; break; @@ -710,7 +709,7 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv case 'b': if (iface_mode == WIFI_MODE_INFRA || iface_mode == WIFI_MODE_AP) { - switch (atoi(state->optarg)) { + switch (atoi(state.optarg)) { case 2: params->band = WIFI_FREQ_BAND_2_4_GHZ; break; @@ -728,7 +727,7 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv } __fallthrough; default: - PR_ERROR("Invalid band: %d\n", atoi(state->optarg)); + PR_ERROR("Invalid band: %d\n", atoi(state.optarg)); return -EINVAL; } } @@ -740,26 +739,26 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv wifi_security_txt(params->security)); return -EINVAL; } - params->mfp = atoi(state->optarg); + params->mfp = atoi(state.optarg); break; case 'm': if (net_bytes_from_str(params->bssid, sizeof(params->bssid), - state->optarg) < 0) { + state.optarg) < 0) { PR_WARNING("Invalid MAC address\n"); return -EINVAL; } break; case 't': if (iface_mode == WIFI_MODE_INFRA) { - params->timeout = strtol(state->optarg, &endptr, 10); + params->timeout = strtol(state.optarg, &endptr, 10); if (*endptr != '\0') { - PR_ERROR("Invalid timeout: %s\n", state->optarg); + PR_ERROR("Invalid timeout: %s\n", state.optarg); return -EINVAL; } } break; case 'a': - params->anon_id = state->optarg; + params->anon_id = state.optarg; params->aid_length = strlen(params->anon_id); if (params->aid_length > WIFI_ENT_IDENTITY_MAX_LEN) { PR_WARNING("anon_id too long (max %d characters)\n", @@ -769,7 +768,7 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv break; case 'B': if (iface_mode == WIFI_MODE_AP) { - switch (atoi(state->optarg)) { + switch (atoi(state.optarg)) { case 1: params->bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ; break; @@ -780,7 +779,7 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv params->bandwidth = WIFI_FREQ_BANDWIDTH_80MHZ; break; default: - PR_ERROR("Invalid bandwidth: %d\n", atoi(state->optarg)); + PR_ERROR("Invalid bandwidth: %d\n", atoi(state.optarg)); return -EINVAL; } } @@ -792,7 +791,7 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv } if (key_passwd_cnt == 0) { - params->key_passwd = state->optarg; + params->key_passwd = state.optarg; params->key_passwd_length = strlen(params->key_passwd); if (params->key_passwd_length > WIFI_ENT_PSWD_MAX_LEN) { PR_WARNING("key_passwd too long (max %d characters)\n", @@ -800,7 +799,7 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv return -EINVAL; } } else if (key_passwd_cnt == 1) { - params->key2_passwd = state->optarg; + params->key2_passwd = state.optarg; params->key2_passwd_length = strlen(params->key2_passwd); if (params->key2_passwd_length > WIFI_ENT_PSWD_MAX_LEN) { PR_WARNING("key2_passwd too long (max %d characters)\n", @@ -811,18 +810,18 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv key_passwd_cnt++; break; case 'S': - params->wpa3_ent_mode = atoi(state->optarg); + params->wpa3_ent_mode = atoi(state.optarg); break; case 'T': - params->TLS_cipher = atoi(state->optarg); + params->TLS_cipher = atoi(state.optarg); break; case 'A': if (iface_mode == WIFI_MODE_INFRA) { - params->verify_peer_cert = !!atoi(state->optarg); + params->verify_peer_cert = !!atoi(state.optarg); } break; case 'V': - params->eap_ver = atoi(state->optarg); + params->eap_ver = atoi(state.optarg); if (params->eap_ver != 0U && params->eap_ver != 1U) { PR_WARNING("eap_ver error %d\n", params->eap_ver); return -EINVAL; @@ -835,10 +834,10 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv return -EINVAL; } - params->eap_identity = state->optarg; + params->eap_identity = state.optarg; params->eap_id_length = strlen(params->eap_identity); - params->identities[params->nusers] = state->optarg; + params->identities[params->nusers] = state.optarg; params->nusers++; if (params->eap_id_length > WIFI_ENT_IDENTITY_MAX_LEN) { PR_WARNING("eap identity too long (max %d characters)\n", @@ -853,10 +852,10 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv return -EINVAL; } - params->eap_password = state->optarg; + params->eap_password = state.optarg; params->eap_passwd_length = strlen(params->eap_password); - params->passwords[params->passwds] = state->optarg; + params->passwords[params->passwds] = state.optarg; params->passwds++; if (params->eap_passwd_length > WIFI_ENT_PSWD_MAX_LEN) { PR_WARNING("eap password length too long (max %d characters)\n", @@ -868,25 +867,25 @@ static int __wifi_args_to_params(const struct shell *sh, size_t argc, char *argv params->ft_used = true; break; case 'g': - params->ignore_broadcast_ssid = shell_strtol(state->optarg, 10, &ret); + params->ignore_broadcast_ssid = shell_strtol(state.optarg, 10, &ret); break; case 'i': /* Unused, but parsing to avoid unknown option error */ break; case 'e': - params->server_cert_domain_exact = state->optarg; + params->server_cert_domain_exact = state.optarg; params->server_cert_domain_exact_len = strlen(params->server_cert_domain_exact); break; case 'x': - params->server_cert_domain_suffix = state->optarg; + params->server_cert_domain_suffix = state.optarg; params->server_cert_domain_suffix_len = strlen(params->server_cert_domain_suffix); break; case 'h': return -ENOEXEC; default: - PR_ERROR("Invalid option %c\n", state->optopt); + PR_ERROR("Invalid option %c\n", state.optopt); return -EINVAL; } @@ -1028,7 +1027,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"type", sys_getopt_required_argument, 0, 't'}, {"bands", sys_getopt_required_argument, 0, 'b'}, @@ -1045,24 +1044,23 @@ static int wifi_scan_args_to_params(const struct shell *sh, *do_scan = true; - while ((opt = sys_getopt_long(argc, argv, "t:b:a:p:s:m:c:i:h", - long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "t:b:a:p:s:m:c:i:h", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 't': - if (!strncasecmp(state->optarg, "passive", 7)) { + if (!strncasecmp(state.optarg, "passive", 7)) { params->scan_type = WIFI_SCAN_TYPE_PASSIVE; - } else if (!strncasecmp(state->optarg, "active", 6)) { + } else if (!strncasecmp(state.optarg, "active", 6)) { params->scan_type = WIFI_SCAN_TYPE_ACTIVE; } else { - PR_ERROR("Invalid scan type %s\n", state->optarg); + PR_ERROR("Invalid scan type %s\n", state.optarg); return -ENOEXEC; } opt_num++; break; case 'b': - if (wifi_utils_parse_scan_bands(state->optarg, ¶ms->bands)) { + if (wifi_utils_parse_scan_bands(state.optarg, ¶ms->bands)) { PR_ERROR("Invalid band value(s)\n"); return -ENOEXEC; } @@ -1070,7 +1068,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, opt_num++; break; case 'a': - val = atoi(state->optarg); + val = atoi(state.optarg); if (val < 0) { PR_ERROR("Invalid dwell_time_active val\n"); @@ -1081,7 +1079,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, opt_num++; break; case 'p': - val = atoi(state->optarg); + val = atoi(state.optarg); if (val < 0) { PR_ERROR("Invalid dwell_time_passive val\n"); @@ -1092,7 +1090,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, opt_num++; break; case 's': - if (wifi_utils_parse_scan_ssids(state->optarg, + if (wifi_utils_parse_scan_ssids(state.optarg, params->ssids, ARRAY_SIZE(params->ssids))) { PR_ERROR("Invalid SSID(s)\n"); @@ -1102,7 +1100,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, opt_num++; break; case 'm': - val = atoi(state->optarg); + val = atoi(state.optarg); if ((val < 0) || (val > WIFI_MGMT_SCAN_MAX_BSS_CNT)) { PR_ERROR("Invalid max_bss val\n"); @@ -1113,7 +1111,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, opt_num++; break; case 'c': - if (wifi_utils_parse_scan_chan(state->optarg, + if (wifi_utils_parse_scan_chan(state.optarg, params->band_chan, ARRAY_SIZE(params->band_chan))) { PR_ERROR("Invalid band or channel value(s)\n"); @@ -1740,7 +1738,7 @@ static int twt_args_to_params(const struct shell *sh, size_t argc, char *argv[], { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; long value; double twt_mantissa_scale = 0.0; double twt_interval_scale = 0.0; @@ -1767,12 +1765,11 @@ static int twt_args_to_params(const struct shell *sh, size_t argc, char *argv[], params->operation = WIFI_TWT_SETUP; - 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 = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "n:c:t:f:r:T:I:a:t:w:p:D:d:e:m:i:h", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 'n': - if (!parse_number(sh, &value, state->optarg, NULL, + if (!parse_number(sh, &value, state.optarg, NULL, WIFI_TWT_INDIVIDUAL, WIFI_TWT_WAKE_TBTT)) { return -EINVAL; @@ -1781,7 +1778,7 @@ static int twt_args_to_params(const struct shell *sh, size_t argc, char *argv[], break; case 'c': - if (!parse_number(sh, &value, state->optarg, NULL, + if (!parse_number(sh, &value, state.optarg, NULL, WIFI_TWT_SETUP_CMD_REQUEST, WIFI_TWT_SETUP_CMD_DEMAND)) { return -EINVAL; @@ -1790,14 +1787,14 @@ static int twt_args_to_params(const struct shell *sh, size_t argc, char *argv[], break; case 't': - if (!parse_number(sh, &value, state->optarg, NULL, 1, 255)) { + if (!parse_number(sh, &value, state.optarg, NULL, 1, 255)) { return -EINVAL; } params->dialog_token = (uint8_t)value; break; case 'f': - if (!parse_number(sh, &value, state->optarg, NULL, 0, + if (!parse_number(sh, &value, state.optarg, NULL, 0, (WIFI_MAX_TWT_FLOWS - 1))) { return -EINVAL; } @@ -1805,35 +1802,35 @@ static int twt_args_to_params(const struct shell *sh, size_t argc, char *argv[], break; case 'r': - if (!parse_number(sh, &value, state->optarg, NULL, 0, 1)) { + if (!parse_number(sh, &value, state.optarg, NULL, 0, 1)) { return -EINVAL; } params->setup.responder = (bool)value; break; case 'T': - if (!parse_number(sh, &value, state->optarg, NULL, 0, 1)) { + if (!parse_number(sh, &value, state.optarg, NULL, 0, 1)) { return -EINVAL; } params->setup.trigger = (bool)value; break; case 'I': - if (!parse_number(sh, &value, state->optarg, NULL, 0, 1)) { + if (!parse_number(sh, &value, state.optarg, NULL, 0, 1)) { return -EINVAL; } params->setup.implicit = (bool)value; break; case 'a': - if (!parse_number(sh, &value, state->optarg, NULL, 0, 1)) { + if (!parse_number(sh, &value, state.optarg, NULL, 0, 1)) { return -EINVAL; } params->setup.announce = (bool)value; break; case 'w': - if (!parse_number(sh, &value, state->optarg, NULL, 1, + if (!parse_number(sh, &value, state.optarg, NULL, 1, WIFI_MAX_TWT_WAKE_INTERVAL_US)) { return -EINVAL; } @@ -1841,7 +1838,7 @@ static int twt_args_to_params(const struct shell *sh, size_t argc, char *argv[], break; case 'p': - if (!parse_number(sh, &value, state->optarg, NULL, 1, + if (!parse_number(sh, &value, state.optarg, NULL, 1, WIFI_MAX_TWT_INTERVAL_US)) { return -EINVAL; } @@ -1849,7 +1846,7 @@ static int twt_args_to_params(const struct shell *sh, size_t argc, char *argv[], break; case 'D': - if (!parse_number(sh, &value, state->optarg, NULL, 0, + if (!parse_number(sh, &value, state.optarg, NULL, 0, WIFI_MAX_TWT_WAKE_AHEAD_DURATION_US)) { return -EINVAL; } @@ -1857,14 +1854,14 @@ static int twt_args_to_params(const struct shell *sh, size_t argc, char *argv[], break; case 'd': - if (!parse_number(sh, &value, state->optarg, NULL, 0, 1)) { + if (!parse_number(sh, &value, state.optarg, NULL, 0, 1)) { return -EINVAL; } params->setup.twt_info_disable = (bool)value; break; case 'e': - if (!parse_number(sh, &value, state->optarg, NULL, 0, + if (!parse_number(sh, &value, state.optarg, NULL, 0, WIFI_MAX_TWT_EXPONENT)) { return -EINVAL; } @@ -1872,7 +1869,7 @@ static int twt_args_to_params(const struct shell *sh, size_t argc, char *argv[], break; case 'm': - if (!parse_number(sh, &value, state->optarg, NULL, 0, 0xFFFF)) { + if (!parse_number(sh, &value, state.optarg, NULL, 0, 0xFFFF)) { return -EINVAL; } params->setup.twt_mantissa = (uint16_t)value; @@ -2149,7 +2146,7 @@ static int wifi_ap_config_args_to_params(const struct shell *sh, size_t argc, ch { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; 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'}, @@ -2162,12 +2159,11 @@ static int wifi_ap_config_args_to_params(const struct shell *sh, size_t argc, ch {0, 0, 0, 0}}; long val; - while ((opt = sys_getopt_long(argc, argv, "t:s:n:c:i:h", - long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "t:s:n:c:i:h", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 't': - if (!parse_number(sh, &val, state->optarg, "max_inactivity", + if (!parse_number(sh, &val, state.optarg, "max_inactivity", 0, WIFI_AP_STA_MAX_INACTIVITY)) { return -EINVAL; } @@ -2175,7 +2171,7 @@ static int wifi_ap_config_args_to_params(const struct shell *sh, size_t argc, ch params->type |= WIFI_AP_CONFIG_PARAM_MAX_INACTIVITY; break; case 's': - if (!parse_number(sh, &val, state->optarg, "max_num_sta", + if (!parse_number(sh, &val, state.optarg, "max_num_sta", 0, CONFIG_WIFI_MGMT_AP_MAX_NUM_STA)) { return -EINVAL; } @@ -2184,11 +2180,11 @@ static int wifi_ap_config_args_to_params(const struct shell *sh, size_t argc, ch break; #if defined(CONFIG_WIFI_NM_HOSTAPD_AP) case 'n': - strncpy(params->ht_capab, state->optarg, WIFI_AP_IEEE_80211_CAPAB_MAX_LEN); + strncpy(params->ht_capab, state.optarg, WIFI_AP_IEEE_80211_CAPAB_MAX_LEN); params->type |= WIFI_AP_CONFIG_PARAM_HT_CAPAB; break; case 'c': - strncpy(params->vht_capab, state->optarg, WIFI_AP_IEEE_80211_CAPAB_MAX_LEN); + strncpy(params->vht_capab, state.optarg, WIFI_AP_IEEE_80211_CAPAB_MAX_LEN); params->type |= WIFI_AP_CONFIG_PARAM_VHT_CAPAB; break; #endif @@ -2199,7 +2195,7 @@ static int wifi_ap_config_args_to_params(const struct shell *sh, size_t argc, ch shell_help(sh); return SHELL_CMD_HELP_PRINTED; default: - PR_ERROR("Invalid option %c\n", state->optopt); + PR_ERROR("Invalid option %c\n", state.optopt); shell_help(sh); return SHELL_CMD_HELP_PRINTED; } @@ -2276,6 +2272,7 @@ static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, bool force = false; bool verbose = false; int opt_index = 0; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"force", sys_getopt_no_argument, 0, 'f'}, {"verbose", sys_getopt_no_argument, 0, 'v'}, @@ -2283,7 +2280,8 @@ static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, {NULL, 0, NULL, 0} }; - while ((opt = sys_getopt_long(argc, argv, "fvi:", long_options, &opt_index)) != -1) { + while ((opt = sys_getopt_long_r(argc, argv, "fvi:", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 'f': force = true; @@ -2299,25 +2297,25 @@ static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, } } - if (sys_getopt_optind == argc) { + if (state.optind == argc) { regd.chan_info = &chan_info[0]; regd.oper = WIFI_MGMT_GET; - } else if (sys_getopt_optind == argc - 1) { - if (strlen(argv[sys_getopt_optind]) != 2) { + } else if (state.optind == argc - 1) { + if (strlen(argv[state.optind]) != 2) { PR_WARNING("Invalid reg domain: Length should be two letters/digits\n"); return -ENOEXEC; } /* Two letter country code with special case of 00 for WORLD */ - if (((argv[sys_getopt_optind][0] < 'A' || argv[sys_getopt_optind][0] > 'Z') || - (argv[sys_getopt_optind][1] < 'A' || argv[sys_getopt_optind][1] > 'Z')) && - (argv[sys_getopt_optind][0] != '0' || argv[sys_getopt_optind][1] != '0')) { - PR_WARNING("Invalid reg domain %c%c\n", argv[sys_getopt_optind][0], - argv[sys_getopt_optind][1]); + if (((argv[state.optind][0] < 'A' || argv[state.optind][0] > 'Z') || + (argv[state.optind][1] < 'A' || argv[state.optind][1] > 'Z')) && + (argv[state.optind][0] != '0' || argv[state.optind][1] != '0')) { + PR_WARNING("Invalid reg domain %c%c\n", argv[state.optind][0], + argv[state.optind][1]); return -ENOEXEC; } - regd.country_code[0] = argv[sys_getopt_optind][0]; - regd.country_code[1] = argv[sys_getopt_optind][1]; + regd.country_code[0] = argv[state.optind][0]; + regd.country_code[1] = argv[state.optind][1]; regd.force = force; regd.oper = WIFI_MGMT_SET; } else { @@ -2646,7 +2644,7 @@ void parse_mode_args_to_params(const struct shell *sh, int argc, int opt; int opt_index = 0; int opt_num = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"iface", sys_getopt_required_argument, 0, 'i'}, {"sta", sys_getopt_no_argument, 0, 's'}, @@ -2657,9 +2655,8 @@ void parse_mode_args_to_params(const struct shell *sh, int argc, {0, 0, 0, 0}}; mode->oper = WIFI_MGMT_GET; - while ((opt = sys_getopt_long(argc, argv, "i:smtpakh", - long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "i:smtpakh", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 's': mode->mode |= WIFI_STA_MODE; @@ -2678,7 +2675,7 @@ void parse_mode_args_to_params(const struct shell *sh, int argc, opt_num++; break; case 'i': - mode->if_index = (uint8_t)atoi(state->optarg); + mode->if_index = (uint8_t)atoi(state.optarg); /* Don't count iface as it's common for both get and set */ break; case 'h': @@ -2749,7 +2746,7 @@ void parse_channel_args_to_params(const struct shell *sh, int argc, { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"iface", sys_getopt_optional_argument, 0, 'i'}, {"channel", sys_getopt_required_argument, 0, 'c'}, @@ -2757,15 +2754,14 @@ void parse_channel_args_to_params(const struct shell *sh, int argc, {"help", sys_getopt_no_argument, 0, 'h'}, {0, 0, 0, 0}}; - while ((opt = sys_getopt_long(argc, argv, "i:c:gh", - long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "i:c:gh", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 'c': - channel->channel = (uint16_t)atoi(state->optarg); + channel->channel = (uint16_t)atoi(state.optarg); break; case 'i': - channel->if_index = (uint8_t)atoi(state->optarg); + channel->if_index = (uint8_t)atoi(state.optarg); break; case 'g': channel->oper = WIFI_MGMT_GET; @@ -2847,7 +2843,7 @@ void parse_filter_args_to_params(const struct shell *sh, int argc, { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"iface", sys_getopt_required_argument, 0, 'i'}, {"capture-len", sys_getopt_optional_argument, 0, 'b'}, @@ -2859,9 +2855,8 @@ void parse_filter_args_to_params(const struct shell *sh, int argc, {"help", sys_getopt_no_argument, 0, 'h'}, {0, 0, 0, 0}}; - while ((opt = sys_getopt_long(argc, argv, "i:b:amcdgh", - long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "i:b:amcdgh", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 'a': filter->filter |= WIFI_PACKET_FILTER_ALL; @@ -2876,10 +2871,10 @@ void parse_filter_args_to_params(const struct shell *sh, int argc, filter->filter |= WIFI_PACKET_FILTER_DATA; break; case 'i': - filter->if_index = (uint8_t)atoi(state->optarg); + filter->if_index = (uint8_t)atoi(state.optarg); break; case 'b': - filter->buffer_size = (uint16_t)atoi(state->optarg); + filter->buffer_size = (uint16_t)atoi(state.optarg); break; case 'h': shell_help(sh); @@ -2971,7 +2966,7 @@ static int parse_dpp_args_auth_init(const struct shell *sh, size_t argc, char *a { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"peer", sys_getopt_required_argument, 0, 'p'}, {"role", sys_getopt_required_argument, 0, 'r'}, @@ -2982,30 +2977,29 @@ static int parse_dpp_args_auth_init(const struct shell *sh, size_t argc, char *a {0, 0, 0, 0}}; int ret = 0; - while ((opt = sys_getopt_long(argc, argv, "p:r:c:m:s:i:", - long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "p:r:c:m:s:i:", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 'p': - params->auth_init.peer = shell_strtol(state->optarg, 10, &ret); + params->auth_init.peer = shell_strtol(state.optarg, 10, &ret); break; case 'r': - params->auth_init.role = shell_strtol(state->optarg, 10, &ret); + params->auth_init.role = shell_strtol(state.optarg, 10, &ret); break; case 'c': - params->auth_init.configurator = shell_strtol(state->optarg, 10, &ret); + params->auth_init.configurator = shell_strtol(state.optarg, 10, &ret); break; case 'm': - params->auth_init.conf = shell_strtol(state->optarg, 10, &ret); + params->auth_init.conf = shell_strtol(state.optarg, 10, &ret); break; case 's': - strncpy(params->auth_init.ssid, state->optarg, WIFI_SSID_MAX_LEN); + strncpy(params->auth_init.ssid, state.optarg, WIFI_SSID_MAX_LEN); break; case 'i': /* Unused, but parsing to avoid unknown option error */ break; default: - PR_ERROR("Invalid option %c\n", state->optopt); + PR_ERROR("Invalid option %c\n", state.optopt); return -EINVAL; } @@ -3023,7 +3017,7 @@ static int parse_dpp_args_chirp(const struct shell *sh, size_t argc, char *argv[ { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"own", sys_getopt_required_argument, 0, 'o'}, {"freq", sys_getopt_required_argument, 0, 'f'}, @@ -3031,21 +3025,20 @@ static int parse_dpp_args_chirp(const struct shell *sh, size_t argc, char *argv[ {0, 0, 0, 0}}; int ret = 0; - while ((opt = sys_getopt_long(argc, argv, "o:f:i:", - long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "o:f:i:", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 'o': - params->chirp.id = shell_strtol(state->optarg, 10, &ret); + params->chirp.id = shell_strtol(state.optarg, 10, &ret); break; case 'f': - params->chirp.freq = shell_strtol(state->optarg, 10, &ret); + params->chirp.freq = shell_strtol(state.optarg, 10, &ret); break; case 'i': /* Unused, but parsing to avoid unknown option error */ break; default: - PR_ERROR("Invalid option %c\n", state->optopt); + PR_ERROR("Invalid option %c\n", state.optopt); return -EINVAL; } @@ -3063,7 +3056,7 @@ static int parse_dpp_args_listen(const struct shell *sh, size_t argc, char *argv { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"role", sys_getopt_required_argument, 0, 'r'}, {"freq", sys_getopt_required_argument, 0, 'f'}, @@ -3071,21 +3064,20 @@ static int parse_dpp_args_listen(const struct shell *sh, size_t argc, char *argv {0, 0, 0, 0}}; int ret = 0; - while ((opt = sys_getopt_long(argc, argv, "r:f:i:", - long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "r:f:i:", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 'r': - params->listen.role = shell_strtol(state->optarg, 10, &ret); + params->listen.role = shell_strtol(state.optarg, 10, &ret); break; case 'f': - params->listen.freq = shell_strtol(state->optarg, 10, &ret); + params->listen.freq = shell_strtol(state.optarg, 10, &ret); break; case 'i': /* Unused, but parsing to avoid unknown option error */ break; default: - PR_ERROR("Invalid option %c\n", state->optopt); + PR_ERROR("Invalid option %c\n", state.optopt); return -EINVAL; } @@ -3103,7 +3095,7 @@ static int parse_dpp_args_btstrap_gen(const struct shell *sh, size_t argc, char { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"type", sys_getopt_required_argument, 0, 't'}, {"opclass", sys_getopt_required_argument, 0, 'o'}, @@ -3113,28 +3105,27 @@ static int parse_dpp_args_btstrap_gen(const struct shell *sh, size_t argc, char {0, 0, 0, 0}}; int ret = 0; - while ((opt = sys_getopt_long(argc, argv, "t:o:h:a:i:", - long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "t:o:h:a:i:", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 't': - params->bootstrap_gen.type = shell_strtol(state->optarg, 10, &ret); + params->bootstrap_gen.type = shell_strtol(state.optarg, 10, &ret); break; case 'o': - params->bootstrap_gen.op_class = shell_strtol(state->optarg, 10, &ret); + params->bootstrap_gen.op_class = shell_strtol(state.optarg, 10, &ret); break; case 'h': - params->bootstrap_gen.chan = shell_strtol(state->optarg, 10, &ret); + params->bootstrap_gen.chan = shell_strtol(state.optarg, 10, &ret); break; case 'a': ret = net_bytes_from_str(params->bootstrap_gen.mac, - WIFI_MAC_ADDR_LEN, state->optarg); + WIFI_MAC_ADDR_LEN, state.optarg); break; case 'i': /* Unused, but parsing to avoid unknown option error */ break; default: - PR_ERROR("Invalid option %c\n", state->optopt); + PR_ERROR("Invalid option %c\n", state.optopt); return -EINVAL; } @@ -3169,7 +3160,7 @@ static int parse_dpp_args_set_config_param(const struct shell *sh, size_t argc, { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"configurator", sys_getopt_required_argument, 0, 'c'}, {"mode", sys_getopt_required_argument, 0, 'm'}, @@ -3178,25 +3169,24 @@ static int parse_dpp_args_set_config_param(const struct shell *sh, size_t argc, {0, 0, 0, 0}}; int ret = 0; - while ((opt = sys_getopt_long(argc, argv, "p:r:c:m:s:i:", - long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "p:r:c:m:s:i:", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 'c': params->configurator_set.configurator = - shell_strtol(state->optarg, 10, &ret); + shell_strtol(state.optarg, 10, &ret); break; case 'm': - params->configurator_set.conf = shell_strtol(state->optarg, 10, &ret); + params->configurator_set.conf = shell_strtol(state.optarg, 10, &ret); break; case 's': - strncpy(params->configurator_set.ssid, state->optarg, WIFI_SSID_MAX_LEN); + strncpy(params->configurator_set.ssid, state.optarg, WIFI_SSID_MAX_LEN); break; case 'i': /* Unused, but parsing to avoid unknown option error */ break; default: - PR_ERROR("Invalid option %c\n", state->optopt); + PR_ERROR("Invalid option %c\n", state.optopt); return -EINVAL; } @@ -3461,7 +3451,7 @@ static int cmd_wifi_dpp_ap_auth_init(const struct shell *sh, size_t argc, char * { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"peer", sys_getopt_required_argument, 0, 'p'}, {"iface", sys_getopt_required_argument, 0, 'i'}, @@ -3472,18 +3462,17 @@ static int cmd_wifi_dpp_ap_auth_init(const struct shell *sh, size_t argc, char * params.action = WIFI_DPP_AUTH_INIT; - while ((opt = sys_getopt_long(argc, argv, "p:i:", - long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "p:i:", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 'p': - params.auth_init.peer = shell_strtol(state->optarg, 10, &ret); + params.auth_init.peer = shell_strtol(state.optarg, 10, &ret); break; case 'i': /* Unused, but parsing to avoid unknown option error */ break; default: - PR_ERROR("Invalid option %c\n", state->optopt); + PR_ERROR("Invalid option %c\n", state.optopt); return -EINVAL; } @@ -3574,7 +3563,7 @@ static int wifi_bgscan_args_to_params(const struct shell *sh, size_t argc, char int err; int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"type", sys_getopt_required_argument, 0, 't'}, {"short-interval", sys_getopt_required_argument, 0, 's'}, @@ -3586,51 +3575,50 @@ static int wifi_bgscan_args_to_params(const struct shell *sh, size_t argc, char unsigned long uval; long val; - while ((opt = sys_getopt_long(argc, argv, "t:s:r:l:b:i:", long_options, - &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "t:s:r:l:b:i:", long_options, + &opt_index, &state)) != -1) { switch (opt) { case 't': - if (strcmp("simple", state->optarg) == 0) { + if (strcmp("simple", state.optarg) == 0) { params->type = WIFI_BGSCAN_SIMPLE; - } else if (strcmp("learn", state->optarg) == 0) { + } else if (strcmp("learn", state.optarg) == 0) { params->type = WIFI_BGSCAN_LEARN; - } else if (strcmp("none", state->optarg) == 0) { + } else if (strcmp("none", state.optarg) == 0) { params->type = WIFI_BGSCAN_NONE; } else { - PR_ERROR("Invalid type %s\n", state->optarg); + PR_ERROR("Invalid type %s\n", state.optarg); shell_help(sh); return SHELL_CMD_HELP_PRINTED; } break; case 's': - uval = shell_strtoul(state->optarg, 10, &err); + uval = shell_strtoul(state.optarg, 10, &err); if (err < 0) { - PR_ERROR("Invalid short interval %s\n", state->optarg); + PR_ERROR("Invalid short interval %s\n", state.optarg); return err; } params->short_interval = uval; break; case 'l': - uval = shell_strtoul(state->optarg, 10, &err); + uval = shell_strtoul(state.optarg, 10, &err); if (err < 0) { - PR_ERROR("Invalid long interval %s\n", state->optarg); + PR_ERROR("Invalid long interval %s\n", state.optarg); return err; } params->long_interval = uval; break; case 'b': - uval = shell_strtoul(state->optarg, 10, &err); + uval = shell_strtoul(state.optarg, 10, &err); if (err < 0) { - PR_ERROR("Invalid BTM queries %s\n", state->optarg); + PR_ERROR("Invalid BTM queries %s\n", state.optarg); return err; } params->btm_queries = uval; break; case 'r': - val = shell_strtol(state->optarg, 10, &err); + val = shell_strtol(state.optarg, 10, &err); if (err < 0) { - PR_ERROR("Invalid RSSI threshold %s\n", state->optarg); + PR_ERROR("Invalid RSSI threshold %s\n", state.optarg); return err; } params->rssi_threshold = val; @@ -3639,7 +3627,7 @@ static int wifi_bgscan_args_to_params(const struct shell *sh, size_t argc, char /* Unused, but parsing to avoid unknown option error */ break; default: - PR_ERROR("Invalid option %c\n", state->optopt); + PR_ERROR("Invalid option %c\n", state.optopt); shell_help(sh); return SHELL_CMD_HELP_PRINTED; } @@ -3680,19 +3668,18 @@ static int wifi_config_args_to_params(const struct shell *sh, size_t argc, char { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; 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 = sys_getopt_long(argc, argv, "o:i:", - long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "o:i:", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 'o': - if (!parse_number(sh, &val, state->optarg, "okc", 0, 1)) { + if (!parse_number(sh, &val, state.optarg, "okc", 0, 1)) { return -EINVAL; } params->okc = val; @@ -3702,7 +3689,7 @@ static int wifi_config_args_to_params(const struct shell *sh, size_t argc, char /* Unused, but parsing to avoid unknown option error */ break; default: - PR_ERROR("Invalid option %c\n", state->optopt); + PR_ERROR("Invalid option %c\n", state.optopt); shell_help(sh); return SHELL_CMD_HELP_PRINTED; } diff --git a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c index 7f2402120c9bf..a66f976021243 100644 --- a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c +++ b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c @@ -117,7 +117,7 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) { int opt; int opt_index = 0; - struct sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; static const struct sys_getopt_option long_options[] = { {"ssid", sys_getopt_required_argument, 0, 's'}, {"passphrase", sys_getopt_required_argument, 0, 'p'}, @@ -143,27 +143,26 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) long channel; long mfp = WIFI_MFP_OPTIONAL; - 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(); + while ((opt = sys_getopt_long_r(argc, argv, "s:p:k:w:b:c:m:t:a:K:h", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 's': - creds.header.ssid_len = strlen(state->optarg); + creds.header.ssid_len = strlen(state.optarg); if (creds.header.ssid_len > WIFI_SSID_MAX_LEN) { shell_warn(sh, "SSID too long (max %d characters)\n", WIFI_SSID_MAX_LEN); return -EINVAL; } - memcpy(creds.header.ssid, state->optarg, creds.header.ssid_len); + memcpy(creds.header.ssid, state.optarg, creds.header.ssid_len); break; case 'k': - creds.header.type = atoi(state->optarg); + creds.header.type = atoi(state.optarg); if (creds.header.type) { secure_connection = true; } break; case 'p': - creds.password_len = strlen(state->optarg); + creds.password_len = strlen(state.optarg); if (creds.password_len < WIFI_PSK_MIN_LEN) { shell_warn(sh, "Passphrase should be minimum %d characters\n", WIFI_PSK_MIN_LEN); @@ -174,12 +173,12 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) WIFI_PSK_MAX_LEN); return -EINVAL; } - memcpy(creds.password, state->optarg, creds.password_len); + memcpy(creds.password, state.optarg, creds.password_len); break; case 'c': - channel = strtol(state->optarg, &endptr, 10); + channel = strtol(state.optarg, &endptr, 10); if (*endptr != '\0') { - shell_error(sh, "Invalid channel: %s\n", state->optarg); + shell_error(sh, "Invalid channel: %s\n", state.optarg); return -EINVAL; } @@ -210,7 +209,7 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) creds.header.channel = channel; break; case 'b': - switch (atoi(state->optarg)) { + switch (atoi(state.optarg)) { case 2: creds.header.flags |= WIFI_CREDENTIALS_FLAG_2_4GHz; break; @@ -221,7 +220,7 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) creds.header.flags |= WIFI_CREDENTIALS_FLAG_6GHz; break; default: - shell_error(sh, "Invalid band: %d\n", atoi(state->optarg)); + shell_error(sh, "Invalid band: %d\n", atoi(state.optarg)); return -EINVAL; } break; @@ -232,9 +231,9 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) wifi_security_txt(creds.header.type)); return -ENOTSUP; } - mfp = strtol(state->optarg, &endptr, 10); + mfp = strtol(state.optarg, &endptr, 10); if (*endptr != '\0') { - shell_error(sh, "Invalid IEEE 802.11w value: %s", state->optarg); + shell_error(sh, "Invalid IEEE 802.11w value: %s", state.optarg); return -EINVAL; } if (mfp == WIFI_MFP_DISABLE) { @@ -243,36 +242,36 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) creds.header.flags |= WIFI_CREDENTIALS_FLAG_MFP_REQUIRED; } else if (mfp > 2) { shell_error(sh, "Invalid IEEE 802.11w value: %s", - state->optarg); + state.optarg); return -EINVAL; } break; case 'm': if (net_bytes_from_str(creds.header.bssid, sizeof(creds.header.bssid), - state->optarg) < 0) { + state.optarg) < 0) { shell_warn(sh, "Invalid MAC address\n"); return -EINVAL; } creds.header.flags |= WIFI_CREDENTIALS_FLAG_BSSID; break; case 'a': - creds.header.aid_length = strlen(state->optarg); + creds.header.aid_length = strlen(state.optarg); if (creds.header.aid_length > WIFI_ENT_IDENTITY_MAX_LEN) { shell_warn(sh, "anon_id too long (max %d characters)\n", WIFI_ENT_IDENTITY_MAX_LEN); return -EINVAL; } - memcpy(creds.header.anon_id, state->optarg, creds.header.aid_length); + memcpy(creds.header.anon_id, state.optarg, creds.header.aid_length); creds.header.flags |= WIFI_CREDENTIALS_FLAG_ANONYMOUS_IDENTITY; break; case 'K': - creds.header.key_passwd_length = strlen(state->optarg); + creds.header.key_passwd_length = strlen(state.optarg); if (creds.header.key_passwd_length > WIFI_ENT_PSWD_MAX_LEN) { shell_warn(sh, "key_passwd too long (max %d characters)\n", WIFI_ENT_PSWD_MAX_LEN); return -EINVAL; } - memcpy(creds.header.key_passwd, state->optarg, + memcpy(creds.header.key_passwd, state.optarg, creds.header.key_passwd_length); creds.header.flags |= WIFI_CREDENTIALS_FLAG_KEY_PASSWORD; break; @@ -280,7 +279,7 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) shell_help(sh); return -ENOEXEC; default: - shell_error(sh, "Invalid option %c\n", state->optopt); + shell_error(sh, "Invalid option %c\n", state.optopt); return -EINVAL; } } diff --git a/subsys/shell/modules/devmem_service.c b/subsys/shell/modules/devmem_service.c index 1e4932ae10039..f843e41b068f6 100644 --- a/subsys/shell/modules/devmem_service.c +++ b/subsys/shell/modules/devmem_service.c @@ -10,11 +10,11 @@ #define _POSIX_C_SOURCE 200809L #include -#include #include #include #include #include +#include static inline bool is_ascii(uint8_t data) { @@ -113,30 +113,28 @@ static int cmd_dump(const struct shell *sh, size_t argc, char **argv) size_t size = -1; size_t width = 32; mem_addr_t addr = -1; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; - sys_getopt_optind = 1; - sys_getopt_init(); - - while ((rv = sys_getopt(argc, argv, "a:s:w:")) != -1) { + while ((rv = sys_getopt_r(argc, argv, "a:s:w:", &state)) != -1) { switch (rv) { case 'a': - addr = (mem_addr_t)shell_strtoul(sys_getopt_optarg, 16, &err); + addr = (mem_addr_t)shell_strtoul(state.optarg, 16, &err); if (err != 0) { - shell_error(sh, "invalid addr '%s'", sys_getopt_optarg); + shell_error(sh, "invalid addr '%s'", state.optarg); return -EINVAL; } break; case 's': - size = (size_t)shell_strtoul(sys_getopt_optarg, 0, &err); + size = (size_t)shell_strtoul(state.optarg, 0, &err); if (err != 0) { - shell_error(sh, "invalid size '%s'", sys_getopt_optarg); + shell_error(sh, "invalid size '%s'", state.optarg); return -EINVAL; } break; case 'w': - width = (size_t)shell_strtoul(sys_getopt_optarg, 0, &err); + width = (size_t)shell_strtoul(state.optarg, 0, &err); if (err != 0) { - shell_error(sh, "invalid width '%s'", sys_getopt_optarg); + shell_error(sh, "invalid width '%s'", state.optarg); return -EINVAL; } break; diff --git a/subsys/shell/shell.c b/subsys/shell/shell.c index c073489973fa1..8bcbb51208369 100644 --- a/subsys/shell/shell.c +++ b/subsys/shell/shell.c @@ -545,10 +545,6 @@ static int exec_cmd(const struct shell *sh, size_t argc, const char **argv, } if (!ret_val) { -#if CONFIG_SHELL_GETOPT - sys_getopt_init(); -#endif - z_flag_cmd_ctx_set(sh, true); /* Unlock thread mutex in case command would like to borrow * shell context to other thread to avoid mutex deadlock. diff --git a/subsys/testsuite/ztest/src/ztest.c b/subsys/testsuite/ztest/src/ztest.c index 28653d06aebb3..32770fde26a79 100644 --- a/subsys/testsuite/ztest/src/ztest.c +++ b/subsys/testsuite/ztest/src/ztest.c @@ -1253,7 +1253,7 @@ 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 sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; int opt; static struct sys_getopt_option long_options[] = { {"suite_iter", sys_getopt_required_argument, 0, 's'}, @@ -1266,11 +1266,11 @@ static int cmd_shuffle(const struct shell *sh, size_t argc, char **argv) int suite_iter = 1; int case_iter = 1; - while ((opt = sys_getopt_long(argc, argv, "s:c:", long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "s:c:", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 's': - val = atoi(state->optarg); + val = atoi(state.optarg); if (val < 1) { shell_error(sh, "Invalid number of suite iterations"); return -ENOEXEC; @@ -1279,7 +1279,7 @@ static int cmd_shuffle(const struct shell *sh, size_t argc, char **argv) opt_num++; break; case 'c': - val = atoi(state->optarg); + val = atoi(state.optarg); if (val < 1) { shell_error(sh, "Invalid number of case iterations"); return -ENOEXEC; @@ -1302,7 +1302,7 @@ 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 sys_getopt_state *state; + struct sys_getopt_state state = SYS_GETOPT_STATE_INITIALIZER; int opt; static struct sys_getopt_option long_options[] = { {"repeat_iter", sys_getopt_required_argument, NULL, 'r'}, @@ -1313,11 +1313,11 @@ static int cmd_run_suite(const struct shell *sh, size_t argc, char **argv) void *param = NULL; int repeat_iter = 1; - while ((opt = sys_getopt_long(argc, argv, "r:p:", long_options, &opt_index)) != -1) { - state = sys_getopt_state_get(); + while ((opt = sys_getopt_long_r(argc, argv, "r:p:", + long_options, &opt_index, &state)) != -1) { switch (opt) { case 'r': - val = atoi(state->optarg); + val = atoi(state.optarg); if (val < 1) { shell_fprintf(sh, SHELL_ERROR, "Invalid number of suite interations\n"); @@ -1327,7 +1327,7 @@ static int cmd_run_suite(const struct shell *sh, size_t argc, char **argv) opt_num++; break; case 'p': - param = state->optarg; + param = state.optarg; opt_num++; break; default: diff --git a/tests/posix/c_lib_ext/src/getopt.c b/tests/posix/c_lib_ext/src/getopt.c index 4fa9a670f0606..891c4fccb4527 100644 --- a/tests/posix/c_lib_ext/src/getopt.c +++ b/tests/posix/c_lib_ext/src/getopt.c @@ -28,11 +28,9 @@ ZTEST(posix_c_lib_ext, test_getopt_basic) int c; char **argv; + optind = 0; /* Reset state */ argv = (char **)nargv; - /* Get state of the current thread */ - getopt_init(); - do { c = getopt(argc, argv, accepted_opt); if (cnt >= strlen(expected)) { @@ -55,7 +53,6 @@ enum getopt_idx { ZTEST(posix_c_lib_ext, test_getopt) { - struct getopt_state *state; static const char *test_opts = "ac:"; static const char *const nargv[] = { [GETOPT_IDX_CMD_NAME] = "cmd_name", @@ -67,9 +64,7 @@ ZTEST(posix_c_lib_ext, test_getopt) char **argv; int c; - /* Get state of the current thread */ - getopt_init(); - + optind = 0; /* Reset state */ argv = (char **)nargv; /* Test uknown option */ @@ -80,12 +75,7 @@ ZTEST(posix_c_lib_ext, test_getopt) zassert_equal(c, 'c', "unexpected opt character"); c = getopt(argc, argv, test_opts); - state = getopt_state_get(); - /* Thread safe usge: */ - zassert_equal(0, strcmp(argv[GETOPT_IDX_OPTARG], state->optarg), - "unexpected optarg result"); - /* Non thread safe usage: */ zassert_equal(0, strcmp(argv[GETOPT_IDX_OPTARG], optarg), "unexpected optarg result"); } @@ -101,7 +91,6 @@ ZTEST(posix_c_lib_ext, test_getopt_long) /* Below test is based on example * https://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Option-Example.html */ - struct getopt_state *state; int verbose_flag = 0; /* getopt_long stores the option index here. */ int option_index = 0; @@ -156,33 +145,31 @@ ZTEST(posix_c_lib_ext, test_getopt_long) int argc4 = ARRAY_SIZE(argv4); /* Test scenario 1 */ - /* Get state of the current thread */ - getopt_init(); + + optind = 0; /* Reset state */ argv = (char **)argv1; c = getopt_long(argc1, argv, accepted_opt, long_options, &option_index); zassert_equal(verbose_flag, 1, "verbose flag expected"); c = getopt_long(argc1, argv, accepted_opt, long_options, &option_index); - state = getopt_state_get(); zassert_equal('c', c, "unexpected option"); - zassert_equal(0, strcmp(state->optarg, argv[GETOPT_LONG_IDX_OPTARG]), "unexpected optarg"); + zassert_equal(0, strcmp(optarg, argv[GETOPT_LONG_IDX_OPTARG]), "unexpected optarg"); c = getopt_long(argc1, argv, accepted_opt, long_options, &option_index); zassert_equal(-1, c, "getopt_long shall return -1"); /* Test scenario 2 */ + optind = 0; /* Reset state */ argv = (char **)argv2; - getopt_init(); c = getopt_long(argc2, argv, accepted_opt, long_options, &option_index); zassert_equal(verbose_flag, 0, "verbose flag expected"); c = getopt_long(argc2, argv, accepted_opt, long_options, &option_index); zassert_equal('d', c, "unexpected option"); - state = getopt_state_get(); - zassert_equal(0, strcmp(state->optarg, argv[GETOPT_LONG_IDX_OPTARG]), "unexpected optarg"); + zassert_equal(0, strcmp(optarg, argv[GETOPT_LONG_IDX_OPTARG]), "unexpected optarg"); c = getopt_long(argc2, argv, accepted_opt, long_options, &option_index); zassert_equal(-1, c, "getopt_long shall return -1"); /* Test scenario 3 */ + optind = 0; /* Reset state */ argv = (char **)argv3; - getopt_init(); c = getopt_long(argc3, argv, accepted_opt, long_options, &option_index); zassert_equal(verbose_flag, 0, "verbose flag expected"); c = getopt_long(argc3, argv, accepted_opt, long_options, &option_index); @@ -191,8 +178,8 @@ ZTEST(posix_c_lib_ext, test_getopt_long) zassert_equal(-1, c, "getopt_long shall return -1"); /* Test scenario 4 */ + optind = 0; /* Reset state */ argv = (char **)argv4; - getopt_init(); c = getopt_long(argc4, argv, accepted_opt, long_options, &option_index); zassert_equal(verbose_flag, 0, "verbose flag expected"); c = getopt_long(argc4, argv, accepted_opt, long_options, &option_index); @@ -208,7 +195,6 @@ ZTEST(posix_c_lib_ext, test_getopt_long_only) /* Below test is based on example * https://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Option-Example.html */ - struct getopt_state *state; int verbose_flag = 0; /* getopt_long stores the option index here. */ int option_index = 0; @@ -263,33 +249,30 @@ ZTEST(posix_c_lib_ext, test_getopt_long_only) int argc4 = ARRAY_SIZE(argv4); /* Test scenario 1 */ + optind = 0; /* Reset state */ argv = (char **)argv1; - getopt_init(); c = getopt_long_only(argc1, argv, accepted_opt, long_options, &option_index); zassert_equal(verbose_flag, 1, "verbose flag expected"); c = getopt_long_only(argc1, argv, accepted_opt, long_options, &option_index); - state = getopt_state_get(); zassert_equal('c', c, "unexpected option"); - zassert_equal(0, strcmp(state->optarg, argv[GETOPT_LONG_IDX_OPTARG]), "unexpected optarg"); + zassert_equal(0, strcmp(optarg, argv[GETOPT_LONG_IDX_OPTARG]), "unexpected optarg"); c = getopt_long_only(argc1, argv, accepted_opt, long_options, &option_index); zassert_equal(-1, c, "getopt_long_only shall return -1"); /* Test scenario 2 */ + optind = 0; /* Reset state */ argv = (char **)argv2; - getopt_init(); - state = getopt_state_get(); c = getopt_long_only(argc2, argv, accepted_opt, long_options, &option_index); zassert_equal(verbose_flag, 0, "verbose flag expected"); c = getopt_long_only(argc2, argv, accepted_opt, long_options, &option_index); - state = getopt_state_get(); zassert_equal('d', c, "unexpected option"); - zassert_equal(0, strcmp(state->optarg, argv[GETOPT_LONG_IDX_OPTARG]), "unexpected optarg"); + zassert_equal(0, strcmp(optarg, argv[GETOPT_LONG_IDX_OPTARG]), "unexpected optarg"); c = getopt_long_only(argc2, argv, accepted_opt, long_options, &option_index); zassert_equal(-1, c, "getopt_long_only shall return -1"); /* Test scenario 3 */ + optind = 0; /* Reset state */ argv = (char **)argv3; - getopt_init(); c = getopt_long_only(argc3, argv, accepted_opt, long_options, &option_index); zassert_equal(verbose_flag, 0, "verbose flag expected"); c = getopt_long_only(argc3, argv, accepted_opt, long_options, &option_index); @@ -298,8 +281,8 @@ ZTEST(posix_c_lib_ext, test_getopt_long_only) zassert_equal(-1, c, "getopt_long_only shall return -1"); /* Test scenario 4 */ + optind = 0; /* Reset state */ argv = (char **)argv4; - getopt_init(); c = getopt_long_only(argc4, argv, accepted_opt, long_options, &option_index); zassert_equal(verbose_flag, 0, "verbose flag expected"); c = getopt_long_only(argc4, argv, accepted_opt, long_options, &option_index);