diff --git a/Makefile b/Makefile index ef4c691..a9adde9 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ -SOURCES := src/main.c src/util/calloc.c src/util/string.c src/util/hash.c src/lexer/lexer.c src/builtins/builtins.c -CFLAGS := -g -O0 -nostdlib +SOURCES := src/main.c src/util/calloc.c src/util/string.c src/util/hash.c src/lexer/lexer.c src/builtins/builtins.c src/util/memset.c +CFLAGS := -Oz -nostdlib UNAME := $(shell uname) ARCH := $(shell uname -m) ifeq ($(UNAME), Linux) -SOURCES += src/system/linux/linux.c src/system/linux/alloc.c src/system/linux/env.c src/system/linux/errno.c -CFLAGS += -fno-stack-protector +SOURCES += src/system/linux/linux.c src/system/linux/alloc.c src/system/linux/env.c src/system/linux/errno.c src/system/linux/signal.c +CFLAGS += -fno-stack-protector -Wno-incompatible-library-redeclaration CFLAGS += -DMSH_ENTRY_POINT="void _start()" ifeq ($(ARCH),i386) SOURCES += src/system/linux/i386.s diff --git a/src/system/linux/linux.c b/src/system/linux/linux.c index 26895b6..d199d2a 100644 --- a/src/system/linux/linux.c +++ b/src/system/linux/linux.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -81,7 +82,7 @@ int msh_execute(char *cmd, char **args) { if (fork == 0) { const char **env_translated = 0; SIZE_TYPE env_translated_size = 0; - int ret, i = 0, n = 0; + SIZE_TYPE ret, i = 0, n = 0; msh_linux_env_item *item_list = env_items; while (item_list->next != 0) { env_translated_size += 1; @@ -105,7 +106,7 @@ int msh_execute(char *cmd, char **args) { env_translated[i++] = 0; msh_linux_end_input_capture(); - ret = (int)SYSCALL(execve, cmd, args, env_translated); + ret = (SIZE_TYPE)SYSCALL(execve, cmd, args, env_translated); for (n = 0; n < i; n++) { msh_deallocate(env_translated[n]); @@ -118,14 +119,28 @@ int msh_execute(char *cmd, char **args) { return ret; } else { - siginfo_t info; - SYSCALL(waitid, P_ALL, 0, &info, WEXITED); + siginfo_t status; + struct rusage ru; + SIZE_TYPE ret; + char *status_str; + + /* msh_linux_setup_signals(); */ + + ret = (SIZE_TYPE)SYSCALL(waitid, P_ALL, fork, &status, WEXITED, &ru); + + /* + status_str = msh_allocate(64); + itoa(status.si_code, status_str, 10); + msh_print_strings("Status ", status_str, "\n", 0); + msh_deallocate(status_str); +*/ + SYSCALL(kill, fork, SIGKILL); SYSCALL(write, 1, "\r", 2); msh_linux_start_input_capture(); - return info.si_code; + return status.si_signo; } return 0; }; diff --git a/src/system/linux/linux.h b/src/system/linux/linux.h index a12233a..2cad83c 100644 --- a/src/system/linux/linux.h +++ b/src/system/linux/linux.h @@ -11,6 +11,8 @@ void msh_linux_env_map_deinit(); void msh_linux_start_input_capture(); void msh_linux_end_input_capture(); +/* void msh_linux_setup_signals(); */ + struct msh_file_t { int fd; }; diff --git a/src/system/linux/signal.c b/src/system/linux/signal.c new file mode 100644 index 0000000..234bf0e --- /dev/null +++ b/src/system/linux/signal.c @@ -0,0 +1,53 @@ +/* Setting up signal handlers is fine but the registers gets clobbered any time + * we return from them. Why? Because go fuck yourself :) and go spend 6 hours + * of your day trying to find out why before giving up :) */ + +/* +#include "linux.h" +#include "syscall.h" +#include + +#define SA_RESTORER 0x04000000 +#include +#include +#include + +#define INIT_SIGNAL(x) \ + SYSCALL(rt_sigaction, x, &sigact, &sigact_old, sizeof(sigset_t)); + +static void signal_handler(int sig) { + char *status_str = msh_allocate(64); + itoa(sig, status_str, 10); + msh_print_strings("\nsignal ", status_str, "\n\n", 0); + msh_deallocate(status_str); +} + +static void signal_restorer(void) { + SYSCALL_0(rt_sigreturn); +} + +void msh_linux_setup_signals() { + struct sigaction sigact; + struct sigaction sigact_old; + + memset(&sigact, 0, sizeof(sigact)); + memset(&sigact_old, 0, sizeof(sigact)); + + sigact.sa_handler = signal_handler; + sigact.sa_restorer = signal_restorer; + sigact.sa_flags = SA_RESTORER | SA_RESTART | SA_SIGINFO; + + SYSCALL(rt_sigprocmask, SIG_UNBLOCK, &sigact.sa_mask, &sigact_old.sa_mask, + sizeof(sigset_t)); + + INIT_SIGNAL(SIGINT); + INIT_SIGNAL(SIGILL); + INIT_SIGNAL(SIGABRT); + INIT_SIGNAL(SIGFPE); + INIT_SIGNAL(SIGSEGV); + INIT_SIGNAL(SIGTERM); + INIT_SIGNAL(SIGHUP); + INIT_SIGNAL(SIGQUIT); + INIT_SIGNAL(SIGTRAP); +} +*/ diff --git a/src/system/linux/syscall.h b/src/system/linux/syscall.h index 0c22887..97723b5 100644 --- a/src/system/linux/syscall.h +++ b/src/system/linux/syscall.h @@ -4,6 +4,7 @@ #define NARGS_SEQ(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N #define NARGS(...) NARGS_SEQ(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1) +#include "../system.h" #include void *syscall_0(void *number); @@ -16,23 +17,33 @@ void *syscall_5(void *number, void *arg1, void *arg2, void *arg3, void *arg4, void *syscall_6(void *number, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, void *arg6); -#define _syscall_0(a) syscall_0((void *)(a)) -#define _syscall_1(a, b) syscall_1((void *)(a), (void *)(b)) -#define _syscall_2(a, b, c) syscall_2((void *)(a), (void *)(b), (void *)(c)) +#define _syscall_0(a) syscall_0((void *)(SIZE_TYPE)(a)) +#define _syscall_1(a, b) \ + syscall_1((void *)(SIZE_TYPE)(a), (void *)(SIZE_TYPE)(b)) +#define _syscall_2(a, b, c) \ + syscall_2((void *)(SIZE_TYPE)(a), (void *)(SIZE_TYPE)(b), \ + (void *)(SIZE_TYPE)(c)) #define _syscall_3(a, b, c, d) \ - syscall_3((void *)(a), (void *)(b), (void *)(c), (void *)(d)) + syscall_3((void *)(SIZE_TYPE)(a), (void *)(SIZE_TYPE)(b), \ + (void *)(SIZE_TYPE)(c), (void *)(SIZE_TYPE)(d)) #define _syscall_4(a, b, c, d, e) \ - syscall_4((void *)(a), (void *)(b), (void *)(c), (void *)(d), (void *)(e)) + syscall_4((void *)(SIZE_TYPE)(a), (void *)(SIZE_TYPE)(b), \ + (void *)(SIZE_TYPE)(c), (void *)(SIZE_TYPE)(d), \ + (void *)(SIZE_TYPE)(e)) #define _syscall_5(a, b, c, d, e, f) \ - syscall_5((void *)(a), (void *)(b), (void *)(c), (void *)(d), (void *)(e), \ - (void *)(f)) + syscall_5((void *)(SIZE_TYPE)(a), (void *)(SIZE_TYPE)(b), \ + (void *)(SIZE_TYPE)(c), (void *)(SIZE_TYPE)(d), \ + (void *)(SIZE_TYPE)(e), (void *)(SIZE_TYPE)(f)) #define _syscall_6(a, b, c, d, e, f, g) \ - syscall_6((void *)(a), (void *)(b), (void *)(c), (void *)(d), (void *)(e), \ - (void *)(f), (void *)(g)) + syscall_6((void *)(SIZE_TYPE)(a), (void *)(SIZE_TYPE)(b), \ + (void *)(SIZE_TYPE)(c), (void *)(SIZE_TYPE)(d), \ + (void *)(SIZE_TYPE)(e), (void *)(SIZE_TYPE)(f), \ + (void *)(SIZE_TYPE)(g)) #define PASTER(x, y) x##_##y #define EVALUATOR(x, y) PASTER(x, y) #define VARIABLE(...) NARGS(__VA_ARGS__) #define FUNC(...) EVALUATOR(_syscall, VARIABLE(__VA_ARGS__)) +#define SYSCALL_0(name) _syscall_0(__NR_##name) #define SYSCALL(name, ...) FUNC(__VA_ARGS__)(__NR_##name, __VA_ARGS__) #endif diff --git a/src/util/calloc.c b/src/util/calloc.c index 2aa9c08..5d2b412 100644 --- a/src/util/calloc.c +++ b/src/util/calloc.c @@ -3,10 +3,6 @@ void *msh_callocate(SIZE_TYPE number, SIZE_TYPE size) { SIZE_TYPE *new, i, s4; new = msh_allocate(number * size); - if (new) { - for (i = 0; i < (number * size); i++) { - new[i] = 0; - } - } + memset(new, 0, number * size); return (new); } diff --git a/src/util/memset.c b/src/util/memset.c new file mode 100644 index 0000000..5fcc4e6 --- /dev/null +++ b/src/util/memset.c @@ -0,0 +1,13 @@ +#include "util.h" + +void *memset(void *b, int c, SIZE_TYPE len) { + int i; + unsigned char *p = b; + i = 0; + while (len > 0) { + *p = c; + p++; + len--; + } + return (b); +} diff --git a/src/util/string.c b/src/util/string.c index 3652673..120a2c2 100644 --- a/src/util/string.c +++ b/src/util/string.c @@ -48,3 +48,37 @@ void msh_str_copy_str(char *dst, char *src) { while ((*dst++ = *src++)) ; }; + +int itoa(int value, char *sp, int radix) { + char tmp[16]; // be careful with the length of the buffer + char *tp = tmp; + int i; + unsigned v; + + int sign = (radix == 10 && value < 0); + if (sign) + v = -value; + else + v = (unsigned)value; + + while (v || tp == tmp) { + i = v % radix; + v /= radix; + if (i < 10) + *tp++ = i + '0'; + else + *tp++ = i + 'a' - 10; + } + + int len = tp - tmp; + + if (sign) { + *sp++ = '-'; + len++; + } + + while (tp > tmp) + *sp++ = *--tp; + + return len; +} diff --git a/src/util/util.h b/src/util/util.h index ef5afbb..11fac54 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -21,4 +21,9 @@ void msh_print_string(char *str); /* Hash string */ unsigned long str_hash(char *str); +/* satisfy glibc */ +void *memset(void *b, int c, SIZE_TYPE len); + +/* convert int to string */ +int itoa(int value, char *sp, int radix); #endif