ref: d59f217f054e105fbc3230aabba5f4780279cff7
parent: d3469c8a968688f658775c60ba29a3d341f05174
author: Quentin Rameau <quinq@fifth.space>
date: Wed Jun 8 12:18:14 EDT 2016
[driver] use dynamic instead of fixed sized tools args This was motivated by the fact that scc shouldn't have an arbitrary limit of passed arguments (but the one imposed by the host), although the most current use case would be less than a decade.
--- a/driver/posix/scc.c
+++ b/driver/posix/scc.c
@@ -14,8 +14,6 @@
#include "../../inc/arg.h"
#include "../../inc/cc.h"
-#define NARGS 64
-
enum {
CC1,
TEEIR,
@@ -29,12 +27,12 @@
};
static struct tool {
- char cmd[PATH_MAX];
- char *args[NARGS];
- char bin[16];
- char *outfile;
- int nargs, in, out, error;
- pid_t pid;
+ char cmd[PATH_MAX];
+ char **args;
+ char bin[16];
+ char *outfile;
+ int nparams, nargs, in, out, init, error;
+ pid_t pid;
} tools[] = {
[CC1] = { .bin = "cc1", .cmd = PREFIX "/libexec/scc/", },
[TEEIR] = { .bin = "tee", .cmd = "tee", },
@@ -48,7 +46,7 @@
char *argv0;
static char *arch;
-static char *tmpobjs[NARGS - 2];
+static char **tmpobjs;
static int nobjs;
static int Eflag, Sflag, kflag;
@@ -70,6 +68,38 @@
}
}
+static char **
+newitem(char **array, int num, char *item)
+{
+ char **ar = xrealloc(array, (num + 1) * sizeof(char **));
+
+ ar[num] = item;
+
+ return ar;
+}
+
+static void
+addarg(int tool, char *arg)
+{
+ struct tool *t = &tools[tool];
+
+ if (t->nargs < 1)
+ t->nargs = 1;
+
+ t->args = newitem(t->args, t->nargs++, arg);
+}
+
+static void
+setargv0(int tool, char *arg)
+{
+ struct tool *t = &tools[tool];
+
+ if (t->nargs > 0)
+ t->args[0] = arg;
+ else
+ t->args = newitem(t->args, t->nargs++, arg);
+}
+
static int
inittool(int tool)
{
@@ -77,39 +107,43 @@
size_t binln;
int n;
- if (!t->args[0]) {
- switch (tool) {
- case CC1:
- case CC2:
- binln = strlen(t->bin);
- if (arch) {
- n = snprintf(t->bin + binln,
- sizeof(t->bin) - binln,
- "-%s", arch);
- if (n < 0 || n >= sizeof(t->bin))
- die("scc: target tool bin too long");
- binln = strlen(t->bin);
- }
+ if (t->init)
+ return tool;
- if (strlen(t->cmd) + binln + 1 > sizeof(t->cmd))
- die("scc: target tool path too long");
- strcat(t->cmd, t->bin);
- break;
- case AS:
- t->nargs = 2;
- t->args[1] = "-o";
- break;
- case LD:
- t->nargs = 2;
- t->args[1] = "-o";
- break;
- default:
- break;
+ switch (tool) {
+ case CC1: /* FALLTHROUGH */
+ case CC2:
+ binln = strlen(t->bin);
+ if (arch) {
+ n = snprintf(t->bin + binln,
+ sizeof(t->bin) - binln,
+ "-%s", arch);
+ if (n < 0 || n >= sizeof(t->bin))
+ die("scc: target tool bin too long");
+ binln = strlen(t->bin);
}
- t->args[0] = t->bin;
+ if (strlen(t->cmd) + binln + 1 > sizeof(t->cmd))
+ die("scc: target tool path too long");
+ strcat(t->cmd, t->bin);
+ break;
+ case LD:
+ addarg(tool, "-o");
+ if (!t->outfile)
+ t->outfile = xstrdup("a.out");
+ addarg(tool, t->outfile);
+ break;
+ case AS:
+ addarg(tool, "-o");
+ break;
+ default:
+ break;
}
+ setargv0(tool, t->bin);
+ t->nparams = t->nargs;
+ t->init = 1;
+
return tool;
}
@@ -142,44 +176,33 @@
return new;
}
-static void
-addarg(int tool, char *arg) {
- struct tool *t = &tools[tool];
-
- if (!(t->nargs < NARGS - 2)) /* 2: argv0, NULL terminator */
- die("scc: too many parameters given");
-
- t->args[++t->nargs] = arg;
-}
-
static int
settool(int tool, char *infile, int nexttool)
{
struct tool *t = &tools[tool];
- int fds[2];
+ int i, fds[2];
static int fdin;
switch (tool) {
case TEEIR:
t->outfile = outfilename(infile, "ir");
- t->args[1] = t->outfile;
+ addarg(tool, t->outfile);
break;
case TEEQBE:
t->outfile = outfilename(infile, "qbe");
- t->args[1] = t->outfile;
+ addarg(tool, t->outfile);
break;
case TEEAS:
t->outfile = outfilename(infile, "as");
- t->args[1] = t->outfile;
+ addarg(tool, t->outfile);
break;
case AS:
t->outfile = outfilename(infile, "o");
- t->args[2] = t->outfile;
+ addarg(tool, t->outfile);
break;
case LD:
- if (!t->outfile)
- t->outfile = xstrdup("a.out");
- t->args[2] = t->outfile;
+ for (i = 0; i < nobjs; ++i)
+ addarg(tool, xstrdup(tmpobjs[i]));
break;
default:
break;
@@ -188,8 +211,8 @@
if (fdin) {
t->in = fdin;
fdin = 0;
- } else {
- t->args[t->nargs + 1] = infile;
+ } else if (infile) {
+ addarg(tool, xstrdup(infile));
}
if (nexttool < LAST_TOOL && tool != AS) {
@@ -199,6 +222,8 @@
fdin = fds[0];
}
+ addarg(tool, NULL);
+
return tool;
}
@@ -227,6 +252,7 @@
break;
}
}
+
static int
toolfor(char *file)
{
@@ -252,7 +278,7 @@
validatetools(void)
{
struct tool *t;
- int tool, st;
+ int i, tool, st;
for (tool = 0; tool < LAST_TOOL; ++tool) {
t = &tools[tool];
if (t->pid) {
@@ -261,8 +287,10 @@
t->error = 1;
exit(-1);
}
- free(t->outfile);
+ for (i = t->nparams; i < t->nargs; ++i)
+ free(t->args[i]);
t->outfile = NULL;
+ t->nargs = t->nparams;
t->pid = 0;
t->error = 0;
}
@@ -272,14 +300,7 @@
static void
linkobjs(void)
{
- int i;
-
- settool(inittool(LD), NULL, LAST_TOOL);
-
- for (i = 0; tmpobjs[i] && i < nobjs; ++i)
- addarg(LD, tmpobjs[i]);
-
- spawn(LD);
+ spawn(settool(inittool(LD), NULL, LAST_TOOL));
validatetools();
if (kflag)
@@ -324,10 +345,12 @@
nexttool = LD;
break;
case LD: /* FALLTHROUGH */
- if (argfile)
- addarg(LD, file);
- else
- tmpobjs[nobjs++] = xstrdup(tools[AS].outfile);
+ if (argfile) {
+ addarg(tool, xstrdup(file));
+ } else {
+ tmpobjs = newitem(tmpobjs, nobjs++,
+ xstrdup(tools[AS].outfile));
+ }
default:
nexttool = LAST_TOOL;
continue;
@@ -376,7 +399,7 @@
arch = EARGF(usage());
break;
case 'o':
- tools[LD].outfile = EARGF(usage());
+ tools[LD].outfile = xstrdup(EARGF(usage()));
break;
case 'w':
addarg(CC1, "-w");