From: Trent Huber Date: Tue, 4 Nov 2025 21:41:24 +0000 (-0500) Subject: Introduce mode builtin X-Git-Url: https://trenthuber.com/code?a=commitdiff_plain;h=f9eba0550019f2fccd301024ee01f54c2896db52;p=thus.git Introduce mode builtin --- diff --git a/src/builtins/mode.c b/src/builtins/mode.c new file mode 100644 index 0000000..0d9a29d --- /dev/null +++ b/src/builtins/mode.c @@ -0,0 +1,23 @@ +#include +#include +#include + +#include "builtin.h" +#include "context.h" +#include "run.h" + +BUILTIN(mode) { + switch (argc) { + case 1: + puts(verbose ? "verbose" : "quiet"); + break; + case 2: + if (strcmp(argv[1], "verbose") == 0) verbose = 1; + else if (strcmp(argv[1], "quiet") == 0) verbose = 0; + else + default: + return usage(argv[0], "[verbose | quiet]"); + } + + return EXIT_SUCCESS; +} diff --git a/src/context.c b/src/context.c index 323527b..372bf50 100644 --- a/src/context.c +++ b/src/context.c @@ -8,7 +8,7 @@ int clear(struct context *c) { c->t = NULL; c->r = NULL; c->current.name[0] = c->buffer[0] = '\0'; - c->current.term = SEMI; + c->prev.term = c->current.term = SEMI; return 1; } diff --git a/src/parse.c b/src/parse.c index dbd2dfd..695246c 100644 --- a/src/parse.c +++ b/src/parse.c @@ -225,14 +225,6 @@ int parse(struct context *c) { return quit(c); } - switch (c->current.term) { - case AND: - case PIPE: - case OR: - note("Expected another command"); - return quit(c); - } - if (c->t == c->tokens) c->t = NULL; if (c->r == c->redirects) c->r = NULL; c->b = NULL; diff --git a/src/run.c b/src/run.c index 4086592..8a1aef1 100644 --- a/src/run.c +++ b/src/run.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -16,6 +17,8 @@ extern char **environ; +int verbose; + static int closepipe(struct command c) { int result; @@ -69,8 +72,8 @@ static void exec(char *path, struct context *c) { } int run(struct context *c) { + char *p; int islist, ispipe, ispipestart, ispipeend; - char *path; pid_t cpid, jobid; static pid_t pipeid; @@ -78,13 +81,33 @@ int run(struct context *c) { if (!parse(c)) return 0; setsig(SIGCHLD, &defaultaction); + if (verbose && (c->t || c->r)) { + if (c->t) { + for (c->t = c->tokens; *c->t; ++c->t) { + for (p = *c->t; *p && *p != ' '; ++p); + p = p == *c->t || *p == ' ' ? "'" : ""; + if (c->t != c->tokens) putchar(' '); + printf("%s%s%s", p, *c->t, p); + } + if (c->r) putchar(' '); + } + if (c->r) for (c->r = c->redirects; c->r->mode; ++c->r) { + if (c->r != c->redirects) putchar(' '); + printf("%d%.*s", c->r->newfd, (c->r->mode & 1) + 1, &"<>>"[c->r->mode & 2]); + if (c->r->oldname) printf("%s", c->r->oldname); + else printf("&%d", c->r->oldfd); + } + if (c->current.term == BG) putchar('&'); + fputs(c->current.term == PIPE ? " | " : "\n", stdout); + } + islist = c->prev.term > BG || c->current.term > BG; if (c->t) { if (c->current.term == BG && bgfull()) { note("Unable to place job in background, too many background jobs"); return quit(c); } - if (!(path = getpath(c->current.name))) { + if (!(p = getpath(c->current.name))) { note("Couldn't find `%s' command", c->current.name); if (c->prev.term == PIPE) killpg(pipeid, SIGKILL); return quit(c); @@ -114,7 +137,7 @@ int run(struct context *c) { fatal("Unable to duplicate write end of `%s' pipe", c->current.name); if (!closepipe(c->current)) exit(EXIT_FAILURE); } - exec(path, c); + exec(p, c); } if (ispipestart) pipeid = cpid; else if (!closepipe(c->prev)) { @@ -126,7 +149,7 @@ int run(struct context *c) { else if ((jobid = cpid = fork()) == -1) { note("Unable to fork child process"); return quit(c); - } else if (cpid == 0) exec(path, c); + } else if (cpid == 0) exec(p, c); if (cpid) { if (setpgid(cpid, jobid) == -1) { @@ -150,7 +173,10 @@ int run(struct context *c) { } else if (c->current.term == OR) return clear(c); } else { if (islist) { - if (c->prev.term == PIPE) killpg(pipeid, SIGKILL); + if (c->prev.term == PIPE) { + killpg(pipeid, SIGKILL); + if (verbose) putchar('\n'); + } note("Expected command"); return quit(c); } diff --git a/src/run.h b/src/run.h index 6dfecfc..9c5cbb8 100644 --- a/src/run.h +++ b/src/run.h @@ -1 +1,3 @@ +extern int verbose; + int run(struct context *c);