environment passthrough
This commit is contained in:
parent
2a3679b272
commit
e0a751eec3
8 changed files with 164 additions and 46 deletions
|
|
@ -171,6 +171,7 @@ void msh_lexer_execute(msh_lexer *lexer) {
|
||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
msh_deallocate(full_path);
|
||||||
}
|
}
|
||||||
if (!exec_success) {
|
if (!exec_success) {
|
||||||
msh_print_strings("msh: ", cmd, ": command not found\n", 0);
|
msh_print_strings("msh: ", cmd, ": command not found\n", 0);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ MSH_ENTRY_POINT {
|
||||||
int i = 0, n = 0, last = 0;
|
int i = 0, n = 0, last = 0;
|
||||||
unsigned long long sz = 0;
|
unsigned long long sz = 0;
|
||||||
|
|
||||||
msh_print_strings(msh_working_directory(), " >", 0);
|
msh_print_strings(msh_working_directory(), " %> ", 0);
|
||||||
|
|
||||||
while ((out = msh_read_input(buf, &sz, 2048)), !out) {
|
while ((out = msh_read_input(buf, &sz, 2048)), !out) {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,20 @@
|
||||||
#include "../system.h"
|
#include "../system.h"
|
||||||
#include "linux.h"
|
#include "linux.h"
|
||||||
#include "syscall.h"
|
|
||||||
|
|
||||||
typedef struct msh_linux_env_item_t msh_linux_env_item;
|
msh_linux_env_item *env_items = 0;
|
||||||
struct msh_linux_env_item_t {
|
msh_linux_env_item *env_item_tail = 0;
|
||||||
unsigned long key;
|
|
||||||
char *value;
|
|
||||||
int is_path;
|
|
||||||
msh_linux_env_item *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
static msh_linux_env_item *env_items = 0;
|
|
||||||
|
|
||||||
void msh_linux_env_map_init() {
|
void msh_linux_env_map_init() {
|
||||||
msh_file *env_file;
|
msh_file *env_file;
|
||||||
SIZE_TYPE file_size;
|
SIZE_TYPE cur;
|
||||||
char *file_buf;
|
char *file_buf;
|
||||||
char ch = 1;
|
char ch = 1;
|
||||||
int counter = 0, i = 0;
|
int counter = 0, i = 0;
|
||||||
msh_linux_env_item *env_item_cur;
|
|
||||||
|
|
||||||
if (!env_items) {
|
if (!env_items) {
|
||||||
env_items = msh_callocate(1, sizeof(msh_linux_env_item));
|
env_items = msh_callocate(1, sizeof(msh_linux_env_item));
|
||||||
}
|
}
|
||||||
env_item_cur = env_items;
|
env_item_tail = env_items;
|
||||||
|
|
||||||
env_file = msh_file_open("/proc/self/environ");
|
env_file = msh_file_open("/proc/self/environ");
|
||||||
file_buf = msh_callocate(512, sizeof(char));
|
file_buf = msh_callocate(512, sizeof(char));
|
||||||
|
|
@ -31,35 +22,39 @@ void msh_linux_env_map_init() {
|
||||||
while (1) {
|
while (1) {
|
||||||
msh_file_read(env_file, &ch, 1);
|
msh_file_read(env_file, &ch, 1);
|
||||||
|
|
||||||
if (ch == ':' && env_item_cur->is_path == 1) {
|
if (ch == ':' && env_item_tail->is_path == 1) {
|
||||||
file_buf[file_size++] = '\0';
|
file_buf[cur++] = '\0';
|
||||||
} else if (ch != '=') {
|
} else if (ch != '=') {
|
||||||
file_buf[file_size++] = ch;
|
file_buf[cur++] = ch;
|
||||||
} else {
|
} else {
|
||||||
file_buf[file_size++] = '\0';
|
file_buf[cur++] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch == '=') {
|
if (ch == '=') {
|
||||||
env_item_cur->key = str_hash(file_buf);
|
env_item_tail->key = msh_allocate(cur);
|
||||||
if (env_item_cur->key == str_hash("PATH")) {
|
msh_str_copy_str(env_item_tail->key, file_buf);
|
||||||
env_item_cur->is_path = 1;
|
env_item_tail->key_len = cur;
|
||||||
|
env_item_tail->key_hash = str_hash(file_buf);
|
||||||
|
if (env_item_tail->key_hash == str_hash("PATH")) {
|
||||||
|
env_item_tail->is_path = 1;
|
||||||
}
|
}
|
||||||
for (i = 0; i < file_size; i++) {
|
for (i = 0; i < cur; i++) {
|
||||||
file_buf[i] = 0;
|
file_buf[i] = 0;
|
||||||
}
|
}
|
||||||
file_size = 0;
|
cur = 0;
|
||||||
} else if (ch == '\0') {
|
} else if (ch == '\0') {
|
||||||
env_item_cur->value = file_buf;
|
env_item_tail->value = file_buf;
|
||||||
env_item_cur->next = msh_callocate(1, sizeof(msh_linux_env_item));
|
env_item_tail->value_len = cur;
|
||||||
|
env_item_tail->next = msh_callocate(1, sizeof(msh_linux_env_item));
|
||||||
|
|
||||||
/* double null for path variables */
|
/* double null for path variables */
|
||||||
if (env_item_cur->is_path) {
|
if (env_item_tail->is_path) {
|
||||||
file_buf[file_size++] = '\0';
|
file_buf[cur++] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
file_buf = msh_callocate(512, sizeof(char));
|
file_buf = msh_callocate(512, sizeof(char));
|
||||||
file_size = 0;
|
cur = 0;
|
||||||
env_item_cur = env_item_cur->next;
|
env_item_tail = env_item_tail->next;
|
||||||
|
|
||||||
counter++;
|
counter++;
|
||||||
|
|
||||||
|
|
@ -78,28 +73,68 @@ void msh_linux_env_map_init() {
|
||||||
void msh_linux_env_map_deinit() {};
|
void msh_linux_env_map_deinit() {};
|
||||||
|
|
||||||
const char *msh_env_get(const char *key) {
|
const char *msh_env_get(const char *key) {
|
||||||
msh_linux_env_item *env_item_cur = env_items;
|
msh_linux_env_item *env_item_tail = env_items;
|
||||||
int hash = str_hash((char *)key);
|
int hash = str_hash((char *)key);
|
||||||
|
|
||||||
while (env_item_cur->next != 0) {
|
while (env_item_tail->next != 0) {
|
||||||
if (env_item_cur->key == hash) {
|
if (env_item_tail->key_hash == hash) {
|
||||||
return env_item_cur->value;
|
return env_item_tail->value;
|
||||||
}
|
}
|
||||||
env_item_cur = env_item_cur->next;
|
env_item_tail = env_item_tail->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *msh_env_get_path() {
|
const char *msh_env_get_path() {
|
||||||
msh_linux_env_item *env_item_cur = env_items;
|
msh_linux_env_item *env_item_tail = env_items;
|
||||||
|
|
||||||
while (env_item_cur->next != 0) {
|
while (env_item_tail->next != 0) {
|
||||||
if (env_item_cur->is_path) {
|
if (env_item_tail->is_path) {
|
||||||
return env_item_cur->value;
|
return env_item_tail->value;
|
||||||
}
|
}
|
||||||
env_item_cur = env_item_cur->next;
|
env_item_tail = env_item_tail->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void msh_env_set(const char *key, char *value) {
|
||||||
|
int hash = str_hash((char *)key);
|
||||||
|
int env_was_set = 0;
|
||||||
|
int key_size = 0, value_size = 0;
|
||||||
|
msh_linux_env_item *env_item_local_cur = env_items;
|
||||||
|
char ch = value[0];
|
||||||
|
|
||||||
|
while (ch != '\0') {
|
||||||
|
ch = value[++value_size];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (env_item_local_cur == 0) {
|
||||||
|
if (env_item_local_cur->key_hash == hash) {
|
||||||
|
msh_exit_shell();
|
||||||
|
env_item_local_cur->value = value;
|
||||||
|
env_item_local_cur->value_len = value_size;
|
||||||
|
env_was_set = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
env_item_local_cur = env_item_local_cur->next;
|
||||||
|
}
|
||||||
|
if (env_was_set == 0) {
|
||||||
|
ch = key[0];
|
||||||
|
|
||||||
|
while (ch != '\0') {
|
||||||
|
ch = key[++key_size];
|
||||||
|
}
|
||||||
|
|
||||||
|
env_item_tail->next = msh_allocate(sizeof(msh_linux_env_item));
|
||||||
|
|
||||||
|
env_item_tail->next->key = (char *)key;
|
||||||
|
env_item_tail->next->key_hash = hash;
|
||||||
|
env_item_tail->next->key_len = key_size;
|
||||||
|
env_item_tail->next->value = value;
|
||||||
|
env_item_tail->next->value_len = value_size;
|
||||||
|
|
||||||
|
env_item_tail = env_item_tail->next;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,44 @@ int msh_execute(char *cmd, char **args) {
|
||||||
}
|
}
|
||||||
SIZE_TYPE fork = (SIZE_TYPE)SYSCALL(fork, 0);
|
SIZE_TYPE fork = (SIZE_TYPE)SYSCALL(fork, 0);
|
||||||
// int fork = 0;
|
// int fork = 0;
|
||||||
|
|
||||||
if (fork == 0) {
|
if (fork == 0) {
|
||||||
int h = (int)SYSCALL(execve, cmd, args, 0);
|
char **env_translated = 0;
|
||||||
if (h == -2) {
|
SIZE_TYPE env_translated_size = 0;
|
||||||
|
int ret, i = 0, n = 0;
|
||||||
|
msh_linux_env_item *item_list = env_items;
|
||||||
|
while (item_list->next != 0) {
|
||||||
|
env_translated_size += 1;
|
||||||
|
item_list = item_list->next;
|
||||||
|
}
|
||||||
|
item_list = env_items;
|
||||||
|
|
||||||
|
env_translated = msh_callocate(env_translated_size + 1, sizeof(char *));
|
||||||
|
while (item_list != 0) {
|
||||||
|
if (item_list->key != 0) {
|
||||||
|
int n = 0;
|
||||||
|
char *entry =
|
||||||
|
msh_allocate(item_list->key_len + item_list->value_len + 2);
|
||||||
|
msh_str_copy_strs(entry, item_list->key, "=", item_list->value, "\0");
|
||||||
|
env_translated[i++] = entry;
|
||||||
|
}
|
||||||
|
item_list = item_list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
env_translated[i++] = 0;
|
||||||
|
|
||||||
|
ret = (int)SYSCALL(execve, cmd, args, env_translated);
|
||||||
|
|
||||||
|
for (n = 0; n < i; n++) {
|
||||||
|
msh_deallocate(env_translated[n]);
|
||||||
|
}
|
||||||
|
msh_deallocate(env_translated);
|
||||||
|
|
||||||
|
if (ret == -2) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return h;
|
|
||||||
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
SYSCALL(waitid, P_ALL, 0, &info, WEXITED);
|
SYSCALL(waitid, P_ALL, 0, &info, WEXITED);
|
||||||
|
|
@ -96,6 +128,11 @@ void msh_set_working_directory(const char *dir) { SYSCALL(chdir, dir); }
|
||||||
|
|
||||||
int msh_path_exists(char *file) { return SYSCALL(access, file, F_OK) == 0; };
|
int msh_path_exists(char *file) { return SYSCALL(access, file, F_OK) == 0; };
|
||||||
|
|
||||||
void msh_backend_init() { msh_linux_env_map_init(); };
|
void msh_backend_init() {
|
||||||
|
msh_linux_env_map_init();
|
||||||
|
|
||||||
|
msh_env_set("TERMF", "test");
|
||||||
|
msh_env_set("TERM", "test");
|
||||||
|
};
|
||||||
|
|
||||||
void msh_backend_deinit() { msh_linux_env_map_deinit(); };
|
void msh_backend_deinit() { msh_linux_env_map_deinit(); };
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,16 @@ struct msh_file_t {
|
||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct msh_linux_env_item_t msh_linux_env_item;
|
||||||
|
struct msh_linux_env_item_t {
|
||||||
|
char *key;
|
||||||
|
unsigned long key_hash;
|
||||||
|
int key_len;
|
||||||
|
char *value;
|
||||||
|
int value_len;
|
||||||
|
int is_path;
|
||||||
|
msh_linux_env_item *next;
|
||||||
|
};
|
||||||
|
extern msh_linux_env_item *env_items;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,6 @@ void msh_backend_deinit();
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
void *msh_allocate(SIZE_TYPE size);
|
void *msh_allocate(SIZE_TYPE size);
|
||||||
|
|
||||||
/* Allocates memory for an array of num objects of size */
|
|
||||||
void *msh_callocate(SIZE_TYPE number, SIZE_TYPE size);
|
|
||||||
|
|
||||||
/* Deallocate memory previously allocated by msh_allocate */
|
/* Deallocate memory previously allocated by msh_allocate */
|
||||||
void msh_deallocate(void *ptr);
|
void msh_deallocate(void *ptr);
|
||||||
|
|
||||||
|
|
@ -91,6 +88,11 @@ int msh_execute(char *cmd, char **args);
|
||||||
*/
|
*/
|
||||||
const char *msh_env_get(const char *key);
|
const char *msh_env_get(const char *key);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set the following environment variable.
|
||||||
|
*/
|
||||||
|
void msh_env_set(const char *key, char *value);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gets a NULL-delimited string representing the folders to search for in the
|
* Gets a NULL-delimited string representing the folders to search for in the
|
||||||
* path, ending in two NULLs.
|
* path, ending in two NULLs.
|
||||||
|
|
|
||||||
|
|
@ -24,3 +24,27 @@ void msh_print_strings(char *str, ...) {
|
||||||
msh_print_string(st);
|
msh_print_string(st);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void msh_str_copy_strs(char *dst, ...) {
|
||||||
|
int i = 0, n = 0;
|
||||||
|
va_list va;
|
||||||
|
|
||||||
|
va_start(va, dst);
|
||||||
|
for (;;) {
|
||||||
|
char *src = va_arg(va, char *);
|
||||||
|
if (src == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while ((dst[i + n] = src[i])) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
n += i;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void msh_str_copy_str(char *dst, char *src) {
|
||||||
|
while ((*dst++ = *src++))
|
||||||
|
;
|
||||||
|
*dst++ = '\0';
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,15 @@
|
||||||
|
|
||||||
#include "../system/system.h"
|
#include "../system/system.h"
|
||||||
|
|
||||||
|
/* Allocates memory for an array of num objects of size */
|
||||||
void *msh_callocate(SIZE_TYPE number, SIZE_TYPE size);
|
void *msh_callocate(SIZE_TYPE number, SIZE_TYPE size);
|
||||||
|
|
||||||
|
/* Copy src string to dst. */
|
||||||
|
void msh_str_copy_str(char *dst, char *src);
|
||||||
|
|
||||||
|
/* Copy NULL terminated array of dst. */
|
||||||
|
void msh_str_copy_strs(char *dst, ...);
|
||||||
|
|
||||||
/* Print NULL terminated array of strings */
|
/* Print NULL terminated array of strings */
|
||||||
void msh_print_strings(char *str, ...);
|
void msh_print_strings(char *str, ...);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue