summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorczjstmax <jstmaxlol@disroot.org>2026-03-18 21:29:42 +0100
committerczjstmax <jstmaxlol@disroot.org>2026-03-18 21:29:42 +0100
commit93fbebf1e805ecd0f18289fbed3effa888212859 (patch)
treece379e15e4b90c73ff5549548c3589f474de8ed8
ver 1
Signed-off-by: czjstmax <jstmaxlol@disroot.org>
-rw-r--r--LICENSE21
-rw-r--r--Makefile14
-rw-r--r--README.md8
-rw-r--r--nosh.c100
4 files changed, 143 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..2de8f20
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 czjstmax <jstmaxlol at disroot dot org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..41d90f7
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+CC = gcc
+IN = nosh.c
+OUT = nsh
+LIBS =
+OPTS = -O0 -g -Wall -Wextra -pedantic
+
+all:
+ $(CC) -o$(OUT) $(LIBS) $(OPTS) $(IN)
+
+run: all
+ ./$(OUT)
+
+clean:
+ rm $(OUT)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2c6edec
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+# nosh - noshell
+a mini POSIX C shell for \*NIX dudes.
+
+### help screen
+```c
+// todo
+```
+
diff --git a/nosh.c b/nosh.c
new file mode 100644
index 0000000..14065c7
--- /dev/null
+++ b/nosh.c
@@ -0,0 +1,100 @@
+/*
+ * nosh - noshell
+ * a 2-hour C shell for POSIX mates
+ *
+ * czjstmax <jstmaxlol at disroot dot org>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <wordexp.h>
+#include <sys/wait.h>
+
+//
+void handlecc(int sig);
+void freeStuff();
+
+//
+char *line = NULL;
+size_t len = 0;
+wordexp_t p;
+
+int main(void)
+{
+ signal(SIGINT, handlecc);
+
+ while (true) {
+ printf("$ ");
+ getline(&line, &len, stdin);
+
+ line[strcspn(line, "\n")] = '\0';
+
+ wordexp(line, &p, 0);
+
+ // debug
+// for (size_t i = 0; i < p.we_wordc; i++) {
+// printf("argv[%zu] = %s\n", i, p.we_wordv[i]);
+// }
+
+ if (strlen(line) == 0)
+ continue; //otherwise.. SIGSEGV!
+ if (strcmp(p.we_wordv[0], ":q") == 0 || strcmp(p.we_wordv[0], "exit") == 0) {
+ freeStuff();
+ return 0;
+ }
+ else if (strcmp(p.we_wordv[0], "echo") == 0) {
+ for (size_t i = 1; i < p.we_wordc; i++)
+ printf("%s ", p.we_wordv[i]);
+ if (p.we_wordc >= 2) {
+ if (strcmp(p.we_wordv[1], "-c") == 0)
+ continue;
+ printf("\n");
+ }
+ }
+ else if (strcmp(p.we_wordv[0], "cd") == 0) {
+ if (chdir(p.we_wordv[1]))
+ perror("nsh! ERROR: failed to change directory");
+ }
+ else if (strcmp(p.we_wordv[0], "clear") == 0) {
+ printf("\033[2J\033[H\033[3J");
+ fflush(stdout);
+ }
+ else {
+ pid_t pid = fork();
+ char **argv = p.we_wordv; // pray with me now
+ if (pid == 0) {
+ char path[strlen("/usr/bin/") + strlen(p.we_wordv[0]) + 1];
+ sprintf(path, "/usr/bin/%s", p.we_wordv[0]);
+ execv(path, argv);
+ perror("nsh! ERROR: failed to execv()");
+ _exit(1);
+ }
+ else if (pid > 0) {
+ int status;
+ waitpid(pid, &status, 0);
+ }
+ else {
+ printf("nsh! couldn't open %s", p.we_wordv[0]);
+ }
+ }
+ }
+}
+
+void handlecc(int sig)
+{
+ printf("\nnsh! %d caught.\nfreeing stuff before quitting.\n", sig);
+ freeStuff();
+ exit(0);
+}
+
+void freeStuff()
+{
+ wordfree(&p);
+ free(line);
+}
+