diff options
| author | czjstmax <jstmaxlol@disroot.org> | 2026-03-19 17:47:36 +0100 |
|---|---|---|
| committer | czjstmax <jstmaxlol@disroot.org> | 2026-03-19 17:47:36 +0100 |
| commit | d9b3d4f234b660d325a4d01479590bced47c9ec4 (patch) | |
| tree | 525b3f0b0c9be220b21b0c9707dc165f8c850ec1 | |
| parent | a7d9fd7c5e927fb93a5902b5ea14fed8998abbba (diff) | |
using GNU readline for history+arrow key handling because i hate
`<termios.h>`
Signed-off-by: czjstmax <jstmaxlol@disroot.org>
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | nm.c | 43 |
2 files changed, 29 insertions, 16 deletions
@@ -1,7 +1,7 @@ CC = gcc IN = nm.c OUT = nshm -LIBS = +LIBS = -lreadline OPTS = -O0 -g -Wall -Wextra -pedantic all: @@ -14,32 +14,44 @@ #include <stdbool.h> #include <wordexp.h> #include <sys/wait.h> +#include <readline/readline.h> +#include <readline/history.h> void handlecc(int sig); -void FreeAll(int n); +void FreeAll(); char *line = NULL; -size_t len = 0; wordexp_t p; int main(void) { signal(SIGINT, handlecc); + char *USER = getenv("USER"); while (true) { - printf("$ "); - getline(&line, &len, stdin); + char prompt[strlen(USER) + strlen("$ ") + 1]; + snprintf(prompt, sizeof(prompt), "%s$ ", USER); - line[strcspn(line, "\n")] = '\0'; + line = readline(prompt); - wordexp(line, &p, 0); + if (!line) + break; + if (*line) + add_history(line); - if (strlen(line) == 0) { - FreeAll(1); + if (wordexp(line, &p, 0) != 0) { + fprintf(stderr, "nsh+! parse error\n"); + free(line); + continue; + } + + // built-ins + if (p.we_wordc == 0) { + FreeAll(); continue; } if (strcmp(p.we_wordv[0], ":q") == 0 || strcmp(p.we_wordv[0], "exit") == 0) { - FreeAll(0); + FreeAll(); return 0; } else if (strcmp(p.we_wordv[0], "echo") == 0) { @@ -54,7 +66,7 @@ int main(void) else if (strcmp(p.we_wordv[0], "cd") == 0) { if (p.we_wordc <= 1) { printf("nsh+! cd: no arguments were given.\n"); - FreeAll(1); + FreeAll(); continue; } if (chdir(p.we_wordv[1])) @@ -84,7 +96,7 @@ int main(void) if (pid == 0) { execvp(p.we_wordv[0], argv); perror("nsh+! ERROR: failed to execvp()"); - FreeAll(0); + FreeAll(); _exit(1); } else if (pid > 0) { @@ -101,13 +113,14 @@ int main(void) void handlecc(int sig) { printf("\nnsh+! %d caught.\nfreeing stuff before quitting.\n", sig); - FreeAll(0); + FreeAll(); exit(0); } -void FreeAll(int n) +void FreeAll() { wordfree(&p); - if (n == 0) - free(line); + free(line); + line = NULL; } + |