scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

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:
Mdriver/posix/scc.c | 61+++++++++++++++++++++++++++++++++++++++----------------------
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);