]> Trent Huber's Code - thus.git/commitdiff
Introduce mode builtin
authorTrent Huber <trentmhuber@gmail.com>
Tue, 4 Nov 2025 21:41:24 +0000 (16:41 -0500)
committerTrent Huber <trentmhuber@gmail.com>
Tue, 4 Nov 2025 21:41:24 +0000 (16:41 -0500)
src/builtins/mode.c [new file with mode: 0644]
src/context.c
src/parse.c
src/run.c
src/run.h

diff --git a/src/builtins/mode.c b/src/builtins/mode.c
new file mode 100644 (file)
index 0000000..0d9a29d
--- /dev/null
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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;
+}
index 323527b32cc0b13158d9b431fdf564a940aa248a..372bf50a1f895e0114a4b70de4358295e9318ffa 100644 (file)
@@ -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;
 }
index dbd2dfd7270dcf7a1d312346db02f718c9d9f6ec..695246c8de3d1df6ccf9c10f97f9eed59aadb70c 100644 (file)
@@ -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;
index 4086592892a92fe5570e490239a61b8eb2813ea8..8a1aef1ecf3185c50b51ecb7bf448719993e5e51 100644 (file)
--- a/src/run.c
+++ b/src/run.c
@@ -1,5 +1,6 @@
 #include <fcntl.h>
 #include <signal.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <sys/errno.h>
 #include <sys/wait.h>
@@ -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);
        }
index 6dfecfc32234c70b7b3d8b148ece868e9e8163a0..9c5cbb8160f5bbe6b58abac81cb4bcfcdf7f832a 100644 (file)
--- a/src/run.h
+++ b/src/run.h
@@ -1 +1,3 @@
+extern int verbose;
+
 int run(struct context *c);