summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE21
-rw-r--r--Makefile14
-rw-r--r--README.md3
-rw-r--r--nm.c113
4 files changed, 151 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..88c9e3a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+CC = gcc
+IN = nm.c
+OUT = nshm
+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..6ee2c73
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# noshmore - noshell more
+an extended version of the [nosh minimal POSIX C shell](https://github.com/jstmaxlol/nosh), still for \*NIX dudes!
+
diff --git a/nm.c b/nm.c
new file mode 100644
index 0000000..7d1cf78
--- /dev/null
+++ b/nm.c
@@ -0,0 +1,113 @@
+/* noshmore
+ * an extended version of nosh,
+ * the minimal POSIX C shell.
+ * -> generally: adds some functionality.
+ *
+ * von 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 FreeAll(int n);
+
+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);
+
+ if (strlen(line) == 0) {
+ FreeAll(1);
+ continue;
+ }
+ if (strcmp(p.we_wordv[0], ":q") == 0 || strcmp(p.we_wordv[0], "exit") == 0) {
+ FreeAll(0);
+ 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)
+ printf("\n");
+ else continue;
+ }
+ }
+ else if (strcmp(p.we_wordv[0], "cd") == 0) {
+ if (p.we_wordc <= 1) {
+ printf("nsh+! cd: no arguments were given.\n");
+ FreeAll(1);
+ continue;
+ }
+ 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 if (strcmp(p.we_wordv[0], "help") == 0) {
+ printf(
+ "noshmore\n"
+ "an extended version of nosh, the minimal POSIX C shell.\n"
+ "\n"
+ "built-ins:\n"
+ "echo -> outputs a string of text, doesn't need \" enclosure.\n"
+ " supports '-c' for output without '\\n'"
+ "clear -> clears screen (and scrollback)\n"
+ "cd -> change working directory\n"
+ "help -> prints this screen\n"
+ "\ngithub repo: github.com/jstmaxlol/noshmore\n"
+ );
+ }
+ else {
+ pid_t pid = fork();
+ char **argv = p.we_wordv; // pray with me now
+ if (pid == 0) {
+ execvp(p.we_wordv[0], argv);
+ perror("nsh+! ERROR: failed to execvp()");
+ FreeAll(0);
+ _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);
+ FreeAll(0);
+ exit(0);
+}
+
+void FreeAll(int n)
+{
+ wordfree(&p);
+ if (n == 0)
+ free(line);
+}