summaryrefslogtreecommitdiff
path: root/src/cmd/jsh
diff options
context:
space:
mode:
authorJacob McDonnell <jacob@jacobmcdonnell.com>2024-03-05 18:46:44 -0500
committerJacob McDonnell <jacob@jacobmcdonnell.com>2024-03-05 18:46:44 -0500
commitc40f400f6ab879e08d54de753aabc987fd6ba07a (patch)
tree295f95070362d14d987638b558ad6bb1ba2415e2 /src/cmd/jsh
parente32262d86c90e2ac73b2c38a47a1bb6b60935098 (diff)
Added a simple shell, jsh
Diffstat (limited to 'src/cmd/jsh')
-rwxr-xr-xsrc/cmd/jsh/README.md3
-rwxr-xr-xsrc/cmd/jsh/jsh.c81
-rwxr-xr-xsrc/cmd/jsh/makefile12
3 files changed, 96 insertions, 0 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <ctype.h>
+
+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