mylsh

my own shell, based on brenns10's
git clone https://github.com/jennydoe/mylsh.git
Log | Files | Refs | Feed | README

commit 4b7efd2201446b196f864b07cf780e2e7c2adce5
parent 90a661b66031dfe95ac4cf9df784531dd328d686
Author: Jenny Doe <tng@soykaf.me>
Date:   Wed, 20 Mar 2019 14:26:06 +0100

fixed: exit builtin and commands exit status

Diffstat:
Mlsh.c | 87++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
1 file changed, 55 insertions(+), 32 deletions(-)

diff --git a/lsh.c b/lsh.c @@ -22,11 +22,10 @@ #include <wchar.h> #include <locale.h> -enum lsh_error { - LSH_EXECUTE_OOM, - LSH_READ_LINE_OOM, - LSH_SPLIT_LINE_OOM -}; +typedef struct lsh_error_ { + int command_status; + int flag; /* 0: success, 1: oom, 2: args, 3: exit */ +} lsh_error; const wchar_t prompt[] = L"λ "; @@ -34,7 +33,7 @@ wchar_t *lsh_read_line(void); wchar_t **lsh_split_line(wchar_t *); int lsh_launch(wchar_t * *); -int lsh_execute(wchar_t * *); +lsh_error lsh_execute(wchar_t * *); int lsh_loop(void); @@ -54,11 +53,14 @@ lsh_siginfo(int __dummy) return; } -int -lsh_execute(wchar_t * *words) -{ +lsh_error +lsh_execute(wchar_t * *words) { + lsh_error status; + status.command_status = 0; + status.flag = 0; + if (words[0] == NULL) - return (0); + return status; #define sc(s) wcscmp(words[0], s) == 0 @@ -73,19 +75,22 @@ lsh_execute(wchar_t * *words) putchar('\n'); } else if (sc(L"pwd")) { - if (words[1] != NULL) + if (words[1] != NULL) { fprintf(stderr, "pwd: too much arguments!\n"); - else { + status.flag = 2; + } else { char buf[MAXPATHLEN]; printf("%s\n", getwd(&buf[0])); } } else if (sc(L"cd") || sc(L"chdir")) { - if (words[1] == NULL) + if (words[1] == NULL) { fprintf(stderr, "cd: missing argument!\n"); - else if (words[2] != NULL) { + status.flag = 2; + } else if (words[2] != NULL) { fprintf(stderr, "cd: too much arguments!\n"); + status.flag = 2; } else { /* @@ -97,24 +102,29 @@ lsh_execute(wchar_t * *words) char *t = malloc(l); if (t == NULL) { fprintf(stderr, "out of memory\n"); - return (LSH_EXECUTE_OOM); + status.flag = 1; + return status; } wcsrtombs(&t[0], v, l, NULL); syslog(LOG_DEBUG, "chdir to %s\n", t); - if (chdir(t) == -1) + if (chdir(t) == -1) { + status.command_status = -1; perror("cd"); + } free(t); } } else if (sc(L"exit")) { - if (words[1] == NULL) + if (words[1] == NULL) { fprintf(stderr, "cd: missing argument!\n"); - else if (words[2] != NULL) { + status.flag = 2; + } else if (words[2] != NULL) { fprintf(stderr, "cd: too much arguments!\n"); + status.flag = 2; } else { int l = 2 + 2 * sizeof(char) * wcslen(words[1]); @@ -122,27 +132,31 @@ lsh_execute(wchar_t * *words) char *t = malloc(l); if (t == NULL) { fprintf(stderr, "out of memory\n"); - return (LSH_EXECUTE_OOM); + status.flag = 1; + goto end; } wcsrtombs(&t[0], v, l, NULL); - int code = atoi(t); + + /* loss of information */ + int code = strtol(t, NULL, 0); free(t); - if (code == 0) - fprintf(stderr, "exit: use something else than 0\n"); - else - syslog(LOG_DEBUG, "exiting with code %d", code); - return (code); + status.flag = 3; + status.command_status = code; } +#undef sc } else { fprintf(stderr, "command not found!\n"); } -#undef sc - return (0); +end: + syslog(LOG_DEBUG, "exiting with code %d", status.command_status); + syslog(LOG_DEBUG, "setting status flag to %d", status.flag); + + return (status); } wchar_t * @@ -234,7 +248,8 @@ lsh_loop(void) { wchar_t *line; wchar_t **words; - int status; + lsh_error status; + int last_status = 0; while (1) { @@ -248,8 +263,16 @@ lsh_loop(void) free(line); free(words); - if (status != 0) - return status; + last_status = status.command_status; + + switch (status.flag){ + case 0: /* everything when right */ + case 1: /* out of memory (for builtins) */ + case 2: /* bad argument count (for builtins) */ + break; + case 3: /* set by exit */ + return last_status; + } } @@ -276,8 +299,8 @@ main(int argc, char *argv[]) int status = lsh_loop(); syslog(LOG_DEBUG, "main loop returned %d", status); - syslog(LOG_DEBUG, "exiting with code 0"); + syslog(LOG_DEBUG, "exiting lsh with code %d", status); /* return status; */ - return (0); + return (status); }