posix: shell: add an environment variable shell command
This service is used to get, set, and unset system environment variables. Note: shell parameter expansion is not supported at this time. Signed-off-by: Christopher Friedt <cfriedt@meta.com>
This commit is contained in:
parent
284cecd4cc
commit
447fc24352
|
@ -3,3 +3,4 @@
|
||||||
|
|
||||||
zephyr_library_sources_ifdef(CONFIG_POSIX_SHELL posix_shell.c)
|
zephyr_library_sources_ifdef(CONFIG_POSIX_SHELL posix_shell.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_POSIX_UNAME_SHELL uname.c)
|
zephyr_library_sources_ifdef(CONFIG_POSIX_UNAME_SHELL uname.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_POSIX_ENV_SHELL env.c)
|
||||||
|
|
|
@ -10,6 +10,7 @@ config POSIX_SHELL
|
||||||
help
|
help
|
||||||
Compile the parent `posix` shell command.
|
Compile the parent `posix` shell command.
|
||||||
|
|
||||||
|
rsource "Kconfig.env"
|
||||||
rsource "Kconfig.uname"
|
rsource "Kconfig.uname"
|
||||||
|
|
||||||
endif # SHELL
|
endif # SHELL
|
||||||
|
|
9
lib/posix/shell/Kconfig.env
Normal file
9
lib/posix/shell/Kconfig.env
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Copyright (c) 2024 Meta
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config POSIX_ENV_SHELL
|
||||||
|
bool "Support for shell"
|
||||||
|
select POSIX_ENV
|
||||||
|
select POSIX_SHELL
|
||||||
|
help
|
||||||
|
This shell provides access to system environment variables.
|
130
lib/posix/shell/env.c
Normal file
130
lib/posix/shell/env.c
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Meta
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "posix_shell.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <zephyr/shell/shell.h>
|
||||||
|
|
||||||
|
#define HELP_ENV_GET "[NAME]"
|
||||||
|
#define HELP_ENV_SET "NAME VALUE | NAME=VALUE"
|
||||||
|
#define HELP_ENV_UNSET "NAME.."
|
||||||
|
|
||||||
|
static int cmd_env_get(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
const char *value;
|
||||||
|
|
||||||
|
switch (argc) {
|
||||||
|
case 1: {
|
||||||
|
extern char **environ;
|
||||||
|
/* list all environment variables */
|
||||||
|
if (environ != NULL) {
|
||||||
|
for (char **envp = environ; *envp != NULL; ++envp) {
|
||||||
|
shell_print(sh, "%s", *envp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case 2:
|
||||||
|
/* list a specific environment variable */
|
||||||
|
name = argv[1];
|
||||||
|
value = getenv(name);
|
||||||
|
if (value != NULL) {
|
||||||
|
shell_print(sh, "%s", value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_shell_env_name(const char *name)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
|
||||||
|
if (name == NULL || name[0] == '\0') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0, N = strlen(name); i < N; ++i) {
|
||||||
|
c = name[i];
|
||||||
|
|
||||||
|
if (c == '_') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isalpha(c)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0 && isdigit(c)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_env_set(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char *value;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
switch (argc) {
|
||||||
|
case 2:
|
||||||
|
name = argv[1];
|
||||||
|
value = strchr(argv[1], '=');
|
||||||
|
if (value != NULL) {
|
||||||
|
*value = '\0';
|
||||||
|
++value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
name = argv[1];
|
||||||
|
value = argv[2];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* silently drop "poorly conditioned" environment variables */
|
||||||
|
if (!is_shell_env_name(name)) {
|
||||||
|
shell_print(sh, "bad name");
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = setenv(name, value, 1);
|
||||||
|
if (ret == -1) {
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_env_unset(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
for (--argc, ++argv; argc > 0; --argc, ++argv) {
|
||||||
|
(void)unsetenv(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_STATIC_SUBCMD_SET_CREATE(sub_env, SHELL_CMD(set, NULL, HELP_ENV_SET, cmd_env_set),
|
||||||
|
SHELL_CMD(get, NULL, HELP_ENV_GET, cmd_env_get),
|
||||||
|
SHELL_CMD(unset, NULL, HELP_ENV_UNSET, cmd_env_unset),
|
||||||
|
SHELL_SUBCMD_SET_END /* Array terminated. */
|
||||||
|
);
|
||||||
|
|
||||||
|
POSIX_CMD_ADD(env, &sub_env, "Print system information", NULL, 1, 255);
|
Loading…
Reference in a new issue