env: Move env_set() out of cmd/nvedit.c and in to env/common.c

Inside of env/common.c we already have our helper env_set_xxx functions,
and even have a comment that explains why env_set() itself wasn't moved.
We now handle that move. This requires that we rename the previous
_do_env_set() to env_do_env_set() and note it as an internal env
function. Add comments about this function to explain why we do this
when we add the prototype. Add a new function, env_inc_id() to allow for
the counter to be updated by both commands and callers, and document
this as well by the prototype.

Signed-off-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
Tom Rini
2023-10-26 14:31:16 -04:00
parent d900449a7a
commit d972192520
5 changed files with 135 additions and 124 deletions

113
env/common.c vendored
View File

@@ -37,11 +37,116 @@ struct hsearch_data env_htab = {
};
/*
* This env_set() function is defined in cmd/nvedit.c, since it calls
* _do_env_set(), whis is a static function in that file.
*
* int env_set(const char *varname, const char *varvalue);
* This variable is incremented each time we set an environment variable so we
* can be check via env_get_id() to see if the environment has changed or not.
* This makes it possible to reread an environment variable only if the
* environment was changed, typically used by networking code.
*/
static int env_id = 1;
int env_get_id(void)
{
return env_id;
}
void env_inc_id(void)
{
env_id++;
}
int env_do_env_set(int flag, int argc, char *const argv[], int env_flag)
{
int i, len;
char *name, *value, *s;
struct env_entry e, *ep;
debug("Initial value for argc=%d\n", argc);
#if !IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_CMD_NVEDIT_EFI)
if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'e')
return do_env_set_efi(NULL, flag, --argc, ++argv);
#endif
while (argc > 1 && **(argv + 1) == '-') {
char *arg = *++argv;
--argc;
while (*++arg) {
switch (*arg) {
case 'f': /* force */
env_flag |= H_FORCE;
break;
default:
return CMD_RET_USAGE;
}
}
}
debug("Final value for argc=%d\n", argc);
name = argv[1];
if (strchr(name, '=')) {
printf("## Error: illegal character '='"
"in variable name \"%s\"\n", name);
return 1;
}
env_inc_id();
/* Delete only ? */
if (argc < 3 || argv[2] == NULL) {
int rc = hdelete_r(name, &env_htab, env_flag);
/* If the variable didn't exist, don't report an error */
return rc && rc != -ENOENT ? 1 : 0;
}
/*
* Insert / replace new value
*/
for (i = 2, len = 0; i < argc; ++i)
len += strlen(argv[i]) + 1;
value = malloc(len);
if (value == NULL) {
printf("## Can't malloc %d bytes\n", len);
return 1;
}
for (i = 2, s = value; i < argc; ++i) {
char *v = argv[i];
while ((*s++ = *v++) != '\0')
;
*(s - 1) = ' ';
}
if (s != value)
*--s = '\0';
e.key = name;
e.data = value;
hsearch_r(e, ENV_ENTER, &ep, &env_htab, env_flag);
free(value);
if (!ep) {
printf("## Error inserting \"%s\" variable, errno=%d\n",
name, errno);
return 1;
}
return 0;
}
int env_set(const char *varname, const char *varvalue)
{
const char * const argv[4] = { "setenv", varname, varvalue, NULL };
/* before import into hashtable */
if (!(gd->flags & GD_FLG_ENV_READY))
return 1;
if (varvalue == NULL || varvalue[0] == '\0')
return env_do_env_set(0, 2, (char * const *)argv, H_PROGRAMMATIC);
else
return env_do_env_set(0, 3, (char * const *)argv, H_PROGRAMMATIC);
}
/**
* Set an environment variable to an integer value