commit fd44eaed3f19041b5e45f9a19fd4df42ddb6d033 Author: hellerve Date: Fri Aug 25 13:44:24 2017 +0200 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e660fd9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +bin/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8fcb8c4 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +TARGET=s +BUILDDIR=bin/ +PREFIX=/usr/local/bin/ +SOURCES=$(wildcard src/*.c) +MAIN=main.c +override LDFLAGS+=-ledit +override CFLAGS+=-Werror -Wall -g -fPIC -O2 -DNDEBUG -ftrapv -Wfloat-equal -Wundef -Wwrite-strings -Wuninitialized -pedantic -std=c11 + +all: main.c + mkdir -p $(BUILDDIR) + $(CC) $(MAIN) $(SOURCES) -o $(BUILDDIR)$(TARGET) $(CFLAGS) $(LDFLAGS) + +install: all + install $(BUILDDIR)$(TARGET) $(PREFIX)$(TARGET) + +uninstall: + rm -rf $(PREFIX)$(TARGET) diff --git a/README.md b/README.md new file mode 100644 index 0000000..cb5d6ca --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# s + +A minimal shell. diff --git a/main.c b/main.c new file mode 100644 index 0000000..5d33c3c --- /dev/null +++ b/main.c @@ -0,0 +1,7 @@ +#include "src/shell.h" + +int main(int argc, char** argv) { + s_loop(); + + return 0; +} diff --git a/src/builtins.c b/src/builtins.c new file mode 100644 index 0000000..9cddcd2 --- /dev/null +++ b/src/builtins.c @@ -0,0 +1,21 @@ +#include "builtins.h" + +const char* s_builtin_names[] = {"cd", "exit"}; +s_builtin s_builtins[] = {&s_cd, &s_exit}; + +int s_cd(char** args) { + if (!args[1]) { + s_error("cd", "expected argument"); + } else { + if (chdir(args[1])) perror("s"); + } + return 1; +} + +int s_exit(char** args) { + return 0; +} + +int s_builtins_count() { + return sizeof(s_builtin_names) / sizeof(const char *); +} diff --git a/src/builtins.h b/src/builtins.h new file mode 100644 index 0000000..815174e --- /dev/null +++ b/src/builtins.h @@ -0,0 +1,12 @@ +#include + +#include "util.h" + +typedef int (*s_builtin)(char**); + +int s_cd(char**); +int s_exit(char**); +int s_builtins_count(); + +extern const char* s_builtin_names[]; +extern s_builtin s_builtins[]; diff --git a/src/shell.c b/src/shell.c new file mode 100644 index 0000000..74e7820 --- /dev/null +++ b/src/shell.c @@ -0,0 +1,84 @@ +#include "shell.h" + +void s_die(const char* msg) { + fprintf(stderr, "s: %s\n", msg); + exit(1); +} + +int s_do(char **args) { + pid_t pid, wpid; + int s; + + pid = fork(); + if (!pid) { + if (execvp(args[0], args) == -1) perror("lsh"); + exit(EXIT_FAILURE); + } else if (pid < 0) { + // Error forking + perror("lsh"); + } else { + do { + wpid = waitpid(pid, &s, WUNTRACED); + } while (!WIFEXITED(s) && !WIFSIGNALED(s)); + } + + return 1; +} + + +char** s_prompt() { + char* line = readline("> "); + int bs = 64; + int pos = 0; + char **tokens = malloc(bs * sizeof(char*)); + char *token; + + + if (!line) return NULL; + + add_history(line); + + if (!tokens) s_die("allocation error"); + + token = strtok(line, " \t\r\n\a"); + + while (token) { + tokens[pos++] = token; + + if (pos >= bs) { + bs += 64; + tokens = realloc(tokens, bs * sizeof(char*)); + if (!tokens) s_die("allocation error"); + } + + token = strtok(NULL, " \t\r\n\a"); + } + tokens[pos] = NULL; + + free(line); + return tokens; +} + +int s_exec(char** args) { + int i; + + if (!args[0]) return 1; + + for (i = 0; i < s_builtins_count(); i++) { + if (!strcmp(args[0], s_builtin_names[i])) return (*s_builtins[i])(args); + } + + return s_do(args); +} + +void s_loop() { + char** cmd; + int s; + + do { + cmd = s_prompt(); + if(!cmd) return; + s = s_exec(cmd); + free(cmd); + } while(s); +} diff --git a/src/shell.h b/src/shell.h new file mode 100644 index 0000000..e2c7c32 --- /dev/null +++ b/src/shell.h @@ -0,0 +1,10 @@ +#include +#include + +#include + +#include "builtins.h" + +void s_loop(); +char** s_prompt(); +int s_exec(char**); diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..4968f65 --- /dev/null +++ b/src/util.c @@ -0,0 +1,5 @@ +#include "util.h" + +void s_error(const char* cmd, const char* msg) { + fprintf(stderr, "%s: %s\n", cmd, msg); +} diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..ef25486 --- /dev/null +++ b/src/util.h @@ -0,0 +1,3 @@ +#include + +void s_error(const char*, const char*);