[hackers] [scc] add per process structs to simplify spawn() || Quentin Rameau

From: <git_AT_suckless.org>
Date: Mon, 30 May 2016 09:22:18 +0200 (CEST)

commit deeb1e9ccd4878ba3b865599dbe8d66d357e1451
Author: Quentin Rameau <quinq_AT_fifth.space>
AuthorDate: Sat May 28 21:40:02 2016 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Mon May 30 09:06:54 2016 +0200

    add per process structs to simplify spawn()
    
    This will be even more useful when we add support for as and ld.

diff --git a/driver/posix/scc.c b/driver/posix/scc.c
index b7be1fc..28a03ea 100644
--- a/driver/posix/scc.c
+++ b/driver/posix/scc.c
_AT_@ -14,51 +14,91 @@
 #include "../../inc/arg.h"
 #include "../../inc/cc.h"
 
-char *argv0;
-
 #define NARGS 64
-static char cmd[FILENAME_MAX];
-static char *argcc1[NARGS], *argcc2[NARGS];
 
-static pid_t pid_cc1, pid_cc2;
+struct tool {
+ char cmd[FILENAME_MAX];
+ char *args[NARGS];
+ char bin[16];
+ char name[8];
+ int in, out;
+ pid_t pid;
+};
+
+typedef struct tool Tool;
+
+char *argv0;
+static Tool cc1 = { .name = "cc1" },
+ cc2 = { .name = "cc2" },
+ qbe = { .name = "qbe", .bin = "qbe", .cmd = "qbe" };
 static char *arch;
 
 static void
 terminate(void)
 {
- if (pid_cc1)
- kill(pid_cc1, SIGTERM);
- if (pid_cc2)
- kill(pid_cc2, SIGTERM);
+ if (cc1.pid)
+ kill(cc1.pid, SIGTERM);
+ if (cc2.pid)
+ kill(cc2.pid, SIGTERM);
+ if (qbe.pid)
+ kill(qbe.pid, SIGTERM);
 }
 
-void
-spawn(char *tool, char *args[NARGS], pid_t *pid_tool, int fd, int stdfd)
+Tool *
+settool(Tool *tool, int pipeout)
 {
- pid_t pid;
- char archtool[16], *fmt = "%s/libexec/scc/%s";
- int r;
+ char *namefmt, *cmdfmt;
+ int fds[2], n;
+ static int fdin;
+
+ if (tool != &qbe) {
+ n = snprintf(tool->bin, sizeof(tool->bin),
+ arch ? "%s-%s" : "%s", tool->name, arch);
+ if (n < 0 || n >= sizeof(tool->bin))
+ die("scc: target tool name too long");
+
+ n = snprintf(tool->cmd, sizeof(tool->cmd),
+ "%s/libexec/scc/%s", PREFIX, tool->bin);
+ if (n < 0 || n >= sizeof(tool->cmd))
+ die("scc: target tool path too long");
+ }
 
- r = snprintf(archtool, sizeof(archtool),
- arch ? "%s-%s" : "%s", tool, arch);
- if (r < 0 || r >= sizeof(archtool))
- die("scc: incorrect target arch");
+ tool->args[0] = tool->bin;
 
- switch (pid = fork()) {
+ if (fdin) {
+ tool->in = fdin;
+ fdin = 0;
+ }
+ if (pipeout) {
+ if (pipe(fds))
+ die("scc: pipe: %s", strerror(errno));
+ tool->out = fds[1];
+ fdin = fds[0];
+ }
+
+ return tool;
+}
+
+void
+spawn(Tool *tool)
+{
+ switch (tool->pid = fork()) {
         case -1:
- die("scc: %s: %s", archtool, strerror(errno));
+ die("scc: %s: %s", tool->name, strerror(errno));
         case 0:
- dup2(fd, stdfd);
- r = snprintf(cmd, sizeof(cmd), fmt, PREFIX, archtool);
- if (r < 0 || r >= sizeof(cmd))
- die("scc: incorrect prefix");
- args[0] = archtool;
- execv(cmd, args);
- fprintf(stderr, "scc: execv %s: %s\n", cmd, strerror(errno));
+ if (tool->out)
+ dup2(tool->out, 1);
+ if (tool->in)
+ dup2(tool->in, 0);
+ execvp(tool->cmd, tool->args);
+ fprintf(stderr, "scc: execv %s: %s\n",
+ tool->cmd, strerror(errno));
                 _exit(1);
         default:
- *pid_tool = pid;
- close(fd);
+ if (tool->in)
+ close(tool->in);
+ if (tool->out)
+ close(tool->out);
                 break;
         }
 }
_AT_@ -72,7 +112,7 @@ usage(void)
 int
 main(int argc, char *argv[])
 {
- int fds[2], st, i;
+ int st, i;
         pid_t pid;
 
         atexit(terminate);
_AT_@ -93,19 +133,25 @@ main(int argc, char *argv[])
         if (!argc)
                 die("scc: fatal error: no input files");
 
- if (pipe(fds))
- die("scc: pipe: %s", strerror(errno));
+ cc1.args[1] = *argv;
 
- argcc1[1] = *argv;
- spawn("cc1", argcc1, &pid_cc1, fds[1], 1);
- spawn("cc2", argcc2, &pid_cc2, fds[0], 0);
+ spawn(settool(&cc1, 1));
+ if (!arch || strcmp(arch, "qbe")) {
+ spawn(settool(&cc2, 0));
+ } else {
+ spawn(settool(&cc2, 1));
+ spawn(settool(&qbe, 0));
+ }
 
- for (i = 0; i < 2; ++i) {
- pid = wait(&st);
- if (pid == pid_cc1)
- pid_cc1 = 0;
- else if (pid == pid_cc2)
- pid_cc2 = 0;
+ for (i = 0; i < 3; ++i) {
+ if ((pid = wait(&st)) < 0)
+ break;
+ if (pid == cc1.pid)
+ cc1.pid = 0;
+ else if (pid == cc2.pid)
+ cc2.pid = 0;
+ else if (pid == qbe.pid)
+ qbe.pid = 0;
                 if (!WIFEXITED(st) || WEXITSTATUS(st) != 0)
                         exit(-1);
         }
Received on Mon May 30 2016 - 09:22:18 CEST

This archive was generated by hypermail 2.3.0 : Mon May 30 2016 - 09:24:13 CEST