commit fe098f45fcb3847ae558bb7027c7701b6d2bc15f
parent d162e39fe5933c79a34e3d2e9acc3fa572ae11da
Author: Quentin Rameau <quinq@fifth.space>
Date: Thu, 30 Jun 2016 17:21:46 +0200
[driver] use random filenames for temporary object
Those are generated in the form scc-XXXXXX and written in PWD or TMPDIR
if it is set.
Diffstat:
1 file changed, 39 insertions(+), 22 deletions(-)
diff --git a/driver/posix/scc.c b/driver/posix/scc.c
@@ -1,5 +1,6 @@
/* See LICENSE file for copyright and license details. */
#define _POSIX_SOURCE
+#define _XOPEN_SOURCE 500
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
@@ -48,7 +49,9 @@ static struct tool {
};
char *argv0;
-static char *arch, *outfile;
+static char *arch, *objfile, *outfile;
+static char *tmpdir;
+static size_t tmpdirln;
static struct items objtmp, objout;
static int Eflag, Sflag, cflag, kflag, sflag;
@@ -136,28 +139,31 @@ inittool(int tool)
static char *
outfilename(char *path, char *ext)
{
- char *new, *name, *dot;
- size_t newsz, nameln;
- int n;
-
- if (!(name = strrchr(path, '/')))
- name = path;
- else
- ++name;
-
- nameln = strlen(name);
-
- if (!(dot = strrchr(name, '.')))
- dot = &name[nameln];
-
- nameln = nameln - strlen(dot);
- newsz = nameln + strlen(ext) + 1 + 1;
+ char *new, *fmt, *p;
+ size_t newsz, pathln;
+ int tmpfd, n;
+
+ if (path) {
+ fmt = "%.0s%.*4$s.%s";
+ if (p = strrchr(path, '/'))
+ path = p + 1;
+ pathln = strlen(path);
+ if (p = strrchr(path, '.'))
+ pathln -= strlen(p);
+ newsz = pathln + 1 + strlen(ext) + 1;
+ } else {
+ fmt = "%s/%s";
+ path = "scc-XXXXXX";
+ newsz = tmpdirln + 1 + strlen(path) + 1;
+ }
new = xmalloc(newsz);
-
- n = snprintf(new, newsz, "%.*s.%s", nameln, name, ext);
+ n = snprintf(new, newsz, fmt, tmpdir, path, ext, pathln);
if (n < 0 || n >= newsz)
die("scc: wrong output filename");
+ if ((tmpfd = mkstemp(new)) < 0 && errno != EINVAL)
+ die("scc: could not create output file");
+ close(tmpfd);
return new;
}
@@ -184,8 +190,13 @@ settool(int tool, char *infile, int nexttool)
addarg(tool, t->outfile);
break;
case AS:
- t->outfile = (cflag && outfile) ? outfile :
- outfilename(infile, "o");
+ if (cflag && outfile) {
+ objfile = outfile;
+ } else {
+ objfile = (cflag || kflag) ? infile : NULL;
+ objfile = outfilename(objfile, "o");
+ }
+ t->outfile = xstrdup(objfile);
addarg(tool, t->outfile);
break;
case LD:
@@ -290,6 +301,8 @@ validatetools(void)
!WIFEXITED(st) || WEXITSTATUS(st) != 0) {
failure = 1;
failed = tool;
+ free(objfile);
+ objfile = NULL;
}
if (tool >= failed && t->outfile)
unlink(t->outfile);
@@ -348,7 +361,7 @@ build(char *file)
}
if (validatetools())
- newitem(objs, outfilename(file, "o"));
+ newitem(objs, objfile);
}
static void
@@ -433,6 +446,10 @@ main(int argc, char *argv[])
if (Eflag && (Sflag || kflag) || argc > 1 && cflag && outfile || !argc)
usage();
+ if (!(tmpdir = getenv("TMPDIR")) || !tmpdir[0])
+ tmpdir = ".";
+ tmpdirln = strlen(tmpdir);
+
for (; *argv; ++argv)
build(*argv);