Squash commits for public release
This commit is contained in:
115
libs/libc/stdlib/env.c
Normal file
115
libs/libc/stdlib/env.c
Normal file
@@ -0,0 +1,115 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void free_var(const char* string)
|
||||
{
|
||||
// TODO: Implement me!
|
||||
}
|
||||
|
||||
char* getenv(const char* name)
|
||||
{
|
||||
size_t len = strlen(name);
|
||||
for (int i = 0; environ[i]; i++) {
|
||||
const char* envv = environ[i];
|
||||
char* eqpos = strchr(envv, '=');
|
||||
if (!eqpos) {
|
||||
continue;
|
||||
}
|
||||
size_t curlen = (size_t)(eqpos - envv);
|
||||
if (curlen == len && strncmp(name, envv, len) == 0) {
|
||||
return (char*)&envv[len + 1];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int setenv(const char* name, const char* value, int overwrite)
|
||||
{
|
||||
if (!overwrite && getenv(name)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int name_len = strlen(name);
|
||||
int value_len = strlen(value);
|
||||
int len = name_len + 1 + value_len;
|
||||
char* string = (char*)malloc(len + 1);
|
||||
strncpy(string, name, name_len);
|
||||
string[name_len] = '=';
|
||||
strncpy(&string[name_len + 1], value, value_len);
|
||||
string[len] = '\0';
|
||||
return putenv(string);
|
||||
}
|
||||
|
||||
int putenv(char* string)
|
||||
{
|
||||
char* pos = strchr(string, '=');
|
||||
if (!pos) {
|
||||
return unsetenv(string);
|
||||
}
|
||||
|
||||
size_t len = (size_t)(pos - string);
|
||||
int env_i = 0;
|
||||
for (; environ[env_i]; env_i++) {
|
||||
const char* envv = environ[env_i];
|
||||
char* eqpos = strchr(envv, '=');
|
||||
if (!eqpos) {
|
||||
continue;
|
||||
}
|
||||
size_t curlen = (size_t)(eqpos - envv);
|
||||
if (len != curlen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(string, envv, len) == 0) {
|
||||
free_var(envv);
|
||||
environ[env_i] = string;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
char** new_environ = (char**)malloc(sizeof(char*) * (env_i + 2));
|
||||
for (int i = 0; i < env_i; i++) {
|
||||
new_environ[i] = environ[i];
|
||||
}
|
||||
new_environ[env_i] = string;
|
||||
new_environ[env_i + 1] = NULL;
|
||||
|
||||
extern int __environ_malloced;
|
||||
if (__environ_malloced) {
|
||||
free(environ);
|
||||
}
|
||||
environ = new_environ;
|
||||
__environ_malloced = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unsetenv(const char* name)
|
||||
{
|
||||
size_t len = strlen(name);
|
||||
int env_i = 0;
|
||||
int remove_pos = 0;
|
||||
const char* remove_env = NULL;
|
||||
for (; environ[env_i]; env_i++) {
|
||||
const char* envv = environ[env_i];
|
||||
char* eqpos = strchr(envv, '=');
|
||||
if (!eqpos) {
|
||||
continue;
|
||||
}
|
||||
size_t curlen = (size_t)(eqpos - envv);
|
||||
if (len != curlen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(name, envv, len) == 0) {
|
||||
remove_pos = env_i;
|
||||
remove_env = envv;
|
||||
}
|
||||
}
|
||||
|
||||
size_t move_len = ((env_i - 1) - remove_pos) * sizeof(char*);
|
||||
memmove(&environ[remove_pos], &environ[remove_pos + 1], move_len);
|
||||
free_var(remove_env);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user