LibC/Shell: Add unsetenv(), and unset builtin calling it in Shell.

This commit is contained in:
Robin Burchell 2019-05-16 14:22:12 +02:00 committed by Andreas Kling
parent b2dd12daac
commit abb7455163
3 changed files with 45 additions and 2 deletions

View file

@ -62,13 +62,40 @@ char* getenv(const char* name)
return nullptr;
}
int unsetenv(char* name)
{
auto new_var_len = strlen(name);
size_t environ_size = 0;
size_t skip = -1;
for (; environ[environ_size]; ++environ_size) {
char* old_var = environ[environ_size];
char* old_eq = strchr(old_var, '=');
ASSERT(old_eq);
auto old_var_len = old_eq - old_var;
if (new_var_len != old_var_len)
continue; // can't match
if (strncmp(name, old_var, new_var_len) == 0)
skip = environ_size;
}
if (skip == -1)
return 0; // not found: no failure.
// Shuffle the existing array down by one.
memmove(&environ[skip], &environ[skip+1], ((environ_size-1)-skip) * sizeof(environ[0]));
environ[environ_size-1] = nullptr;
return 0;
}
int putenv(char* new_var)
{
char* new_eq = strchr(new_var, '=');
// FIXME: should remove the var from the environment.
if (!new_eq)
return 0;
return unsetenv(new_var);
auto new_var_len = new_eq - new_var;
size_t environ_size = 0;

View file

@ -16,6 +16,7 @@ void free(void*);
void* realloc(void *ptr, size_t);
char* getenv(const char* name);
int putenv(char*);
int unsetenv(char*);
int atoi(const char*);
long atol(const char*);
long long atoll(const char*);

View file

@ -80,6 +80,17 @@ static int sh_export(int argc, char** argv)
return 0;
}
static int sh_unset(int argc, char** argv)
{
if (argc != 2) {
fprintf(stderr, "usage: unset variable\n");
return 1;
}
unsetenv(argv[1]);
return 0;
}
static int sh_cd(int argc, char** argv)
{
char pathbuf[PATH_MAX];
@ -167,6 +178,10 @@ static bool handle_builtin(int argc, char** argv, int& retval)
retval = sh_export(argc, argv);
return true;
}
if (!strcmp(argv[0], "unset")) {
retval = sh_unset(argc, argv);
return true;
}
if (!strcmp(argv[0], "history")) {
retval = sh_history(argc, argv);
return true;