summaryrefslogtreecommitdiff
path: root/nm.c
diff options
context:
space:
mode:
Diffstat (limited to 'nm.c')
-rw-r--r--nm.c113
1 files changed, 113 insertions, 0 deletions
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);
+}