ref: ba3a4b9f50ac53f5753efc115c24a250b3168cb8
parent: 6408599f6398af4a1c0913c1ee8b1e63c4e4fb4a
author: Quentin Rameau <quinq@fifth.space>
date: Sat May 28 17:40:02 EDT 2016
add per process structs to simplify spawn() This will be even more useful when we add support for as and ld.
--- a/driver/posix/scc.c
+++ b/driver/posix/scc.c
@@ -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;
- r = snprintf(archtool, sizeof(archtool),
- arch ? "%s-%s" : "%s", tool, arch);
- if (r < 0 || r >= sizeof(archtool))
- die("scc: incorrect target arch");
+ 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");
- switch (pid = fork()) {
+ 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");
+ }
+
+ tool->args[0] = tool->bin;
+
+ 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;
}
}
@@ -72,7 +112,7 @@
int
main(int argc, char *argv[])
{
- int fds[2], st, i;
+ int st, i;
pid_t pid;
atexit(terminate);
@@ -93,19 +133,25 @@
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);
}