From c40f400f6ab879e08d54de753aabc987fd6ba07a Mon Sep 17 00:00:00 2001 From: Jacob McDonnell Date: Tue, 5 Mar 2024 18:46:44 -0500 Subject: Added a simple shell, jsh --- src/cmd/jsh/README.md | 3 ++ src/cmd/jsh/jsh.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/cmd/jsh/makefile | 12 ++++++++ 3 files changed, 96 insertions(+) create mode 100755 src/cmd/jsh/README.md create mode 100755 src/cmd/jsh/jsh.c create mode 100755 src/cmd/jsh/makefile (limited to 'src/cmd/jsh') diff --git a/src/cmd/jsh/README.md b/src/cmd/jsh/README.md new file mode 100755 index 0000000..db638ed --- /dev/null +++ b/src/cmd/jsh/README.md @@ -0,0 +1,3 @@ +#J-Shell (jsh) + +J-Shell is a simple unix shell written in C. diff --git a/src/cmd/jsh/jsh.c b/src/cmd/jsh/jsh.c new file mode 100755 index 0000000..320a93d --- /dev/null +++ b/src/cmd/jsh/jsh.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include +#include + +size_t getargs(const size_t n, char *args[n], FILE * const stream); +int shellexec(size_t n, char * const args[n]); + +static bool run = true; + +int main(int argc, char *argv[]) { + char *words[BUFSIZ] = {NULL}; + FILE *fp = stdin; + size_t numberofwords = 0; + if (argc == 2) { + if ((fp = fopen(argv[1], "r")) == NULL) { + perror("jsh"); + return EXIT_FAILURE; + } + } + while (run) { + printf("$ "); + numberofwords = getargs(BUFSIZ, words, fp); + shellexec(BUFSIZ, words); + for (int i = 0; i < numberofwords; i++) { + free(words[i]); + words[i] = NULL; + } + } + return 0; +} + +size_t getargs(const size_t n, char *args[n], FILE * const stream) { + size_t i = 0; + char c = 0, s[BUFSIZ], *sp = s; + memset(s, '\0', sizeof(s)); + while ((c = fgetc(stream)) != EOF && i < n && sp < s + BUFSIZ) { + if (isspace(c)) { + *sp = '\0'; + args[i++] = strdup(s); + sp = s; + if (strcmp(args[i-1], "") == 0) { + free(args[i-1]); + args[i-1] = NULL; + i--; + } + if (c == '\n') { + break; + } + } else { + *sp++ = c; + } + } + return i; +} + +int shellexec(size_t n, char * const args[n]) { + if (strcmp(args[0], "exit") == 0) { + run = false; + return 0; + } + pid_t pid = fork(); + int status; + if (pid == 0) { + if (execvp(args[0], args) == -1) { + perror("jsh"); + } + exit(EXIT_FAILURE); + } else if (pid < 0) { + perror("jsh"); + exit(EXIT_FAILURE); + } else { + do { + waitpid(pid, &status, WUNTRACED); + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + } + return 0; +} + diff --git a/src/cmd/jsh/makefile b/src/cmd/jsh/makefile new file mode 100755 index 0000000..72d7d68 --- /dev/null +++ b/src/cmd/jsh/makefile @@ -0,0 +1,12 @@ +CFLAGS=-Wall -Werror + +build: jsh + @cp jsh $(PROROOT)/build/bin/jsh + +jsh: jsh.c + $(CC) $(CFLAGS) -o jsh jsh.c + +clean: + @rm -r jsh + +.PHONY: build clean -- cgit v1.2.3