Skip to content

Commit

Permalink
posix: shell: add an environment variable shell command
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
cfriedt committed Jan 31, 2024
1 parent 6b1990f commit a5f196d
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/posix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ if(CONFIG_POSIX_API OR CONFIG_PTHREAD_IPC OR CONFIG_POSIX_CLOCK OR
endif()

zephyr_library()
zephyr_library_compile_options(-U_POSIX_C_SOURCE -D_POSIX_C_SOURCE=200809L)

add_subdirectory_ifdef(CONFIG_GETOPT getopt)
add_subdirectory_ifdef(CONFIG_SHELL shell)
zephyr_library_sources_ifdef(CONFIG_EVENTFD eventfd.c)
Expand Down
1 change: 1 addition & 0 deletions lib/posix/shell/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@

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_ENV_SHELL env.c)
2 changes: 2 additions & 0 deletions lib/posix/shell/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ config POSIX_SHELL

rsource "Kconfig.uname"

rsource "Kconfig.env"

endif # SHELL
9 changes: 9 additions & 0 deletions lib/posix/shell/Kconfig.env
Original file line number Diff line number Diff line change
@@ -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 changes: 130 additions & 0 deletions lib/posix/shell/env.c
Original file line number Diff line number Diff line change
@@ -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);

0 comments on commit a5f196d

Please sign in to comment.