diff options
| -rw-r--r-- | core/env.c | 81 | ||||
| -rw-r--r-- | core/powerctl.c | 29 | ||||
| -rw-r--r-- | core/test_env | 1 | ||||
| -rw-r--r-- | lib/env/Makefile | 2 | ||||
| -rw-r--r-- | lib/env/env.c | 55 | ||||
| -rw-r--r-- | lib/io/Makefile | 2 | ||||
| -rw-r--r-- | lib/io/io.c | 22 | ||||
| -rw-r--r-- | lib/io/io.h | 7 | ||||
| -rwxr-xr-x | lib/io/test | bin | 0 -> 36104 bytes | |||
| -rw-r--r-- | lib/sys/reboot.h | 3 | ||||
| -rw-r--r-- | lib/sys/sync.h | 11 | ||||
| -rw-r--r-- | smash/Makefile | 2 | ||||
| -rw-r--r-- | smash/comment.c | 6 | ||||
| -rw-r--r-- | smash/comment.h | 6 | ||||
| -rw-r--r-- | smash/main.c | 72 |
15 files changed, 263 insertions, 36 deletions
diff --git a/core/env.c b/core/env.c new file mode 100644 index 0000000..e96be59 --- /dev/null +++ b/core/env.c @@ -0,0 +1,81 @@ +#include "../lib/io/io.h" +#include "../lib/sys/sizes.h" +#include "../lib/sys/execve.h" +#include "../lib/env/env.h" + +#define BUFSIZ 1024 +char buf[BUFSIZ] = ""; + + +void add_to_env(char *line, u64 linenumber) +{ + char *key; + char *value; + + key = line; + + while (*line != '=' && *line) ++line; + + if (!*line) { + wff(STDERR_FD, "error: %i no valid environment line\n", linenumber); + return; + } + + *(line++) = 0; + value = line; + + while (*line != '\n' && *line) ++line; + + if (*line == '\n') *line = 0; + + setenv(key, value); +} + + +int main(int argc, const char **argv) +{ + if (argc == 1) { + const char**envp = getenvp(); + + while (*envp) { + wstdf("%s\n", *envp); + ++envp; + } + + return 0; + } + + u64 fd = STDIN_FD; + u64 size; + char *p; + u64 linenumber = 1; + const char **execargv = argv + 1; + + if (argv[1][0] == '-' && argv[1][1] == 'f') { + if (argc > 3) { + fd = open(argv[2], OPEN_READ_ONLY, 0); + if (fd < 0) { + wff(STDERR_FD, "venv: cannot open file '%s'\n", argv[2]); + return -1; + } + execargv = argv + 3; + } else { + wf(STDERR_FD, "venv [-f file] command [args...]\n"); + return -1; + } + } + + while ((size = read(fd, buf, BUFSIZ - 1))) { + p = buf; + + while (p < buf + BUFSIZ && *p != '\n') ++p; + *(++p) = 0; + + add_to_env(buf, linenumber++); + } + + execve(execargv[0], execargv, getenvp()); + + wff(STDERR_FD, "cannot execute '%s'\n", execargv[0]); + return -1; +} diff --git a/core/powerctl.c b/core/powerctl.c new file mode 100644 index 0000000..cf887bf --- /dev/null +++ b/core/powerctl.c @@ -0,0 +1,29 @@ +#include "../lib/sys/reboot.h" +#include "../lib/cstr/cstr.h" +#include "../lib/io/io.h" +#include "../lib/sys/sync.h" + +int main(int argc, char **argv) { + if (argc != 2) { + wf(STDERR_FD, "powerctl [poweroff|reboot|halt|hard-reset|suspend]\n"); + return -1; + } + + char *command = argv[1]; + + sync(); + + if (cstr_compare(command, "poweroff")) { + reboot(REBOOT_POWEROFF); + } else if (cstr_compare(command, "reboot")) { + reboot(REBOOT_RESTART); + } else if (cstr_compare(command, "halt")) { + reboot(REBOOT_HALT_SYSTEM); + } else if (cstr_compare(command, "hard-reset")) { + reboot(REBOOT_HARD_RESET); + } else if (cstr_compare(command, "suspend")) { + reboot(REBOOT_SUSPEND); + } + + return -1; +} diff --git a/core/test_env b/core/test_env new file mode 100644 index 0000000..561cdd6 --- /dev/null +++ b/core/test_env @@ -0,0 +1 @@ +TEST=TEST diff --git a/lib/env/Makefile b/lib/env/Makefile index db9b5a8..128490b 100644 --- a/lib/env/Makefile +++ b/lib/env/Makefile @@ -1,3 +1,3 @@ unit_test: - gcc env.c ../io/io.c ../cstr/cstr.c ../sys/start.S -o test -static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -DENV_UNIT_TEST -g + gcc env.c ../io/io.c ../aec/aec.c ../malloc/malloc.c ../cstr/cstr.c ../sys/start.S -o test -static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -DENV_UNIT_TEST -g ./test diff --git a/lib/env/env.c b/lib/env/env.c index d52c3f3..7ceaa15 100644 --- a/lib/env/env.c +++ b/lib/env/env.c @@ -1,16 +1,19 @@ #include "env.h" #include "../malloc/malloc.h" +#include "../cstr/cstr.h" -const char **envp; +char **envp; +u64 envsize = 0; +#define ENVSIZEINC 16 -const char **__getenvpair(const char *key); +char **__getenvpair(const char *key); u8 __match_env_key(const char *p, const char *key); const char *getenv(const char *key) { - const char **p = __getenvpair(key); + char **p = __getenvpair(key); const char *value; if (p == 0) @@ -25,14 +28,44 @@ const char *getenv(const char *key) void setenv(const char *key, const char *value) { - const char **p = __getenvpair(key); - *p = value; + char **p = __getenvpair(key); + + if (p == 0) { + p = envp; + + while (*p) ++p; + + if (p - envp >= envsize) { + if (envsize == 0) { + for (; *(envp + envsize); ++envsize); + char **nenvp = malloc(sizeof(char *) * (envsize + ENVSIZEINC)); + p = nenvp; + while (p < nenvp + envsize + ENVSIZEINC) *(p++) = 0; + p = nenvp; + while (*envp) *(p++) = *(envp++); + envp = nenvp; + } else { + envp = realloc(envp, envsize + ENVSIZEINC); + } + + p = envp + envsize; + envsize += ENVSIZEINC; + } + } + + *p = malloc((cstr_length(key) + cstr_length(key)) + 2); + char *i = *p; + + while (*key) *(i++) = *(key++); + *(i++) = '='; + while (*value) *(i++) = *(value++); + *i = 0; } -const char **__getenvpair(const char *key) +char **__getenvpair(const char *key) { - const char **p = envp; + char **p = envp; while (*p) { if (__match_env_key(*p, key)) { @@ -48,7 +81,7 @@ const char **__getenvpair(const char *key) const char **getenvp() { - return envp; + return (const char**)envp; } @@ -69,7 +102,7 @@ u8 __match_env_key(const char *p, const char *key) return 1; } -void init_env(int argc, const char **argv, const char **envp__) +void init_env(int argc, const char **argv, char **envp__) { envp = envp__; } @@ -80,7 +113,9 @@ void init_env(int argc, const char **argv, const char **envp__) int main(int argc, const char **argv) { - wstdf("HOME: %s\n", getenv("HOSTNAME")); + wstdf("TEST: %s\n", getenv("TEST")); + setenv("TEST", "Hello, World!"); + wstdf("TEST: %s\n", getenv("TEST")); } #endif diff --git a/lib/io/Makefile b/lib/io/Makefile index 73aa785..46d1d43 100644 --- a/lib/io/Makefile +++ b/lib/io/Makefile @@ -1,3 +1,3 @@ unit_test: - gcc io.c ../aec/aec.c ../cstr/cstr.c ../env/env.c ../sys/start.S -o test -static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -DIO_LIB_UNIT_TEST -g + gcc io.c ../malloc/malloc.c ../aec/aec.c ../cstr/cstr.c ../env/env.c ../sys/start.S -o test -static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -DIO_LIB_UNIT_TEST -g ./test diff --git a/lib/io/io.c b/lib/io/io.c index e8384f3..7dee314 100644 --- a/lib/io/io.c +++ b/lib/io/io.c @@ -20,36 +20,48 @@ void rstd(char *buf, unsigned long count) read(STDIN_FD, buf, count); } + +void wf(unsigned int fd, char *buf) +{ + write(fd, buf, cstr_length(buf)); +} + void wstdf__(const char *buf, const void **args) { + wff__(STDOUT_FD, buf, args); +} + + +void wff__(unsigned int fd, const char *buf, const void **args) +{ const char *start = buf; char stoi_buf[32] = ""; int i; for (; *buf; ++buf) { if (*buf == '%') { if (buf - start > 0) - __wstdn(start, buf - start); + write(fd, start, buf - start); ++buf; switch (*buf) { case '%': __wstdn("%", 1); break; case 's': - __wstdn(((const char **)args)[0], cstr_length(((const char**)args)[0])); + write(fd, ((const char **)args)[0], cstr_length(((const char**)args)[0])); ++args; break; case 'i': for (i = 0; i < 32; ++i) stoi_buf[i] = 0; i64_to_cstr(((u64 *)args)[0], stoi_buf, 32); - __wstdn(stoi_buf, cstr_length(stoi_buf)); + write(fd, stoi_buf, cstr_length(stoi_buf)); ++args; break; case 'u': for (i = 0; i < 32; ++i) stoi_buf[i] = 0; u64_to_cstr(((u64 *)args)[0], stoi_buf, 32); - __wstdn(stoi_buf, cstr_length(stoi_buf)); + write(fd, stoi_buf, cstr_length(stoi_buf)); ++args; break; case 'S': @@ -71,7 +83,7 @@ void wstdf__(const char *buf, const void **args) } if (buf - start > 0) - __wstdn(start, buf - start); + write(fd, start, buf - start); } #ifdef IO_LIB_UNIT_TEST diff --git a/lib/io/io.h b/lib/io/io.h index 06cc541..c373cd0 100644 --- a/lib/io/io.h +++ b/lib/io/io.h @@ -5,13 +5,20 @@ void wstd(const char *buf); void rstd(char *buf, unsigned long count); +void wf(unsigned int fd, char *buf); void wstdf__(const char *buf, const void **args); +void wff__(unsigned int fd, const char *buf, const void **args); #define wstdf(buf, ...) { \ const void *__wstdf__args__[] = { __VA_ARGS__ }; \ wstdf__(buf, __wstdf__args__); \ } +#define wff(fd, buf, ...) { \ + const void *__wstdf__args__[] = { __VA_ARGS__ }; \ + wff__(fd, buf, __wstdf__args__); \ +} + #endif diff --git a/lib/io/test b/lib/io/test Binary files differnew file mode 100755 index 0000000..ce7db41 --- /dev/null +++ b/lib/io/test diff --git a/lib/sys/reboot.h b/lib/sys/reboot.h index 22893ca..824fbc3 100644 --- a/lib/sys/reboot.h +++ b/lib/sys/reboot.h @@ -7,9 +7,10 @@ #define REBOOT_HARD_RESET 0x01234567 #define REBOOT_ENABLE_CAD 0x89abcdef #define REBOOT_DISABLE_CAD 0 -#define REBOOT_POWEROFF 0x4321fedc +#define REBOOT_RESTART 0x4321fedc #define REBOOT_SUSPEND 0xd000fce2 #define REBOOT_NEW_KERNEL 0x45584543 +#define REBOOT_POWEROFF 0x01234567 static int reboot(int cmd) { diff --git a/lib/sys/sync.h b/lib/sys/sync.h new file mode 100644 index 0000000..fe61454 --- /dev/null +++ b/lib/sys/sync.h @@ -0,0 +1,11 @@ +#ifndef SYS_H +#define SYS_H + +#include "syscalls.h" + +void sync() +{ + syscall(SYNC); +} + +#endif diff --git a/smash/Makefile b/smash/Makefile index 8bae278..1d8e228 100644 --- a/smash/Makefile +++ b/smash/Makefile @@ -17,4 +17,4 @@ unit_test_exec: ./test all: - gcc main.c exec.c parser.c builtin.c ../lib/slib.a -static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -fno-builtin -o smash -DVARIABLES_UNIT_TEST -g + gcc main.c comment.c exec.c parser.c builtin.c ../lib/slib.a -static -nostdlib -fno-stack-protector -Wno-implicit-function-declaration -fno-builtin -o smash -DVARIABLES_UNIT_TEST -g diff --git a/smash/comment.c b/smash/comment.c new file mode 100644 index 0000000..8171cf1 --- /dev/null +++ b/smash/comment.c @@ -0,0 +1,6 @@ +#include "comment.h" + +void remove_comment(char *line) { + while (*line && *line != '#') ++line; + *line = 0; +} diff --git a/smash/comment.h b/smash/comment.h new file mode 100644 index 0000000..f20877f --- /dev/null +++ b/smash/comment.h @@ -0,0 +1,6 @@ +#ifndef COMMENT_H +#define COMMENT_H + +void remove_comment(char *line); + +#endif diff --git a/smash/main.c b/smash/main.c index ed41b70..4d81f18 100644 --- a/smash/main.c +++ b/smash/main.c @@ -1,52 +1,90 @@ #include "exec.h" +#include "comment.h" #include "../lib/sys/io.h" #include "../lib/cstr/cstr.h" #include "../lib/sys/dup2.h" +#include "../lib/sys/exit.h" #include "../lib/io/io.h" #include "../lib/sys/errno.h" -#define BUFSIZ 1024 +#define BUFSIZ 16384 -void clear_buf(char *buf) +char buf[BUFSIZ] = {0}; +int getline(int fd, char *linebuf) { - for (int i = 0; i < BUFSIZ; ++i) - buf[i] = 0; + u64 size = 0; + char *line = buf; + + while (*line && *line != '\n') line++; + + if (!*line) { + u64 s = cstr_length(buf); + s = read(fd, buf + s, BUFSIZ - s - 1); + + if (s == 0) { + return -1; + } + + buf[s] = 0; + while (*line && *line != '\n') line++; + + if (!*line) { + wf(STDERR_FD, "line too long to handle, exiting.\n"); + exit(-1); + } + } + + *line = 0; + ++line; + + size = cstr_length(buf); + for (int i = 0; buf[i]; ++i) linebuf[i] = buf[i]; + linebuf[size] = 0; + + buf[0] = 0; + for (int i = 0; *line; ++i) { + buf[i] = *line; + buf[i + 1] = 0; + ++line; + } + + return size; } int main(int argc, char *argv[], char *envp[]) { - char buf[BUFSIZ] = {0}; char prompt[] = "$ "; - u64 line_length; + i64 line_length; int fd = STDIN_FD; + char linebuf[BUFSIZ]; if (argc == 2) { fd = open(argv[1], OPEN_READ_ONLY, 0); - if (fd < 0) - wstdf("%s\n", errstr[-fd]); + if (fd < 0) { + wff(STDERR_FD, "smash: %s\n", errstr[-fd]); + return -1; + } } while (1) { if (fd == STDIN_FD) - write(STDOUT_FD, prompt, cstr_length(prompt)); - int p = read(fd, buf, BUFSIZ); - line_length = cstr_length(buf); + wstd(prompt); + line_length = getline(fd, linebuf); - if (line_length == 0) + if (line_length == -1) { break; + } - if (buf[line_length - 1] == '\n') - buf[--line_length] = 0; + remove_comment(linebuf); + line_length = cstr_length(linebuf); if (line_length > 0) { - exec(buf); + exec(linebuf); } - - clear_buf(buf); } if (fd != STDOUT_FD) |