mylsh

my own shell, based on brenns10's
Log | Files | Refs | Feed

commit 0cc7ff9e4f2baae234d9fcf7bccbe1d9e7fedf79
Author: Jenny Doe <tng@soykaf.me>
Date:   Tue, 19 Mar 2019 16:01:46 +0100

birthday!

Diffstat:
Alsh.c | 175+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 175 insertions(+), 0 deletions(-)

diff --git a/lsh.c b/lsh.c @@ -0,0 +1,175 @@ +/* + * what is this ? I read the code at https://github.com/brenns10/lsh and + * noticed it was remarkably simple to understand so I studied it for a few + * 10 minutes and then tried to program it from memory; this is the result. I + * will gradually add features. + * + * It does compile with `-ansi -pedantic` but I plan on only supporting c99 + * for now. Just compile using `cc --std=c99 lsh.c` + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/param.h> + +#include <wchar.h> +#include <locale.h> + +const wchar_t prompt[] = L"λ "; + +wchar_t *lsh_read_line(void); +wchar_t **lsh_split_line(wchar_t *); + +int lsh_launch(wchar_t * *); +int lsh_execute(wchar_t * *); + +int +lsh_execute(wchar_t * *words) +{ + if (words[0] == NULL) + return (0); + +#define sc(s) wcscmp(words[0], s) == 0 + if (sc(L"echo")) { + for (int i = 1; words[i] != NULL; i++) + printf("%ls\n", words[i]); + + //to mimick classic 'echo' + if (words[1] == NULL) + putchar('\n'); + } else if (sc(L"pwd")) { + if (words[1] != NULL) + fprintf(stderr, "too much arguments!"); + else { + char buf[MAXPATHLEN]; + printf("%s\n", getwd(&buf[0])); + } + } else { + fprintf(stderr, "command not found!\n"); + return (0); + } +#undef sc + + return (0); +} + +wchar_t * +lsh_read_line(void) +{ + wchar_t *line = malloc(sizeof(wchar_t) * 1); + if (line == NULL) { + fprintf(stderr, "out of memory"); + exit(1); + } + + wchar_t c; + int bufsize = 1; + int pos = 0; + + if (feof(stdin)) { + putchar('\n'); + exit(0); + } + + if (isatty(fileno(stdin))) + printf("%ls", prompt); + + while ((c = getwchar()) != '\n' && c != WEOF) { + line[pos] = c; + ++pos; + + if (pos >= bufsize) { + bufsize += 1; + line = realloc(line, sizeof(wchar_t) * bufsize); + if (line == NULL) { + fprintf(stderr, "out of memory"); + exit(1); + } + + } + + } + +eol: + line[pos] = '\0'; + + //fprintf(stderr, "%ls\n", line); + return line; +} + +wchar_t ** +lsh_split_line(wchar_t * line) +{ + wchar_t **words = malloc(sizeof(wchar_t *) * 10); + if (words == NULL) { + fprintf(stderr, "out of memory"); + exit(1); + } + + wchar_t *word; + wchar_t *dummy; + int bufsize = 10; + int pos = 0; + +#define s L" \t\r\n" + word = wcstok(line, s, &dummy); + while (1) { + words[pos] = word; + if (word == NULL) + break; + //fprintf(stderr, "%ls\n", word); + ++pos; + if (pos >= bufsize) { + bufsize += 10; + words = realloc(words, sizeof(wchar_t *) * + bufsize); + if (words == NULL) { + fprintf(stderr, "out of memory"); + exit(1); + } + + } + word = wcstok(NULL, s, &dummy); + } +#undef s + return words; +} + +void +lsh_loop(void) +{ + wchar_t *line; + wchar_t **words; + int status; + + while (1) { + line = lsh_read_line(); + words = lsh_split_line(line); + status = lsh_execute(words); + + free(line); + free(words); + + if (status != 0) + break; + + } +} + +int +main(void) +{ + (void)setlocale(LC_ALL, ""); + + /* + * default umask for the shell and its child processes + */ + umask(022); + + lsh_loop(); + + return (0); +}